EOJ mouthly 2020.3 Bおよびマトリックス

ここに画像の説明を挿入他人の解決策を研究した後、ビット操作の理解を深める必要があります。

emmmmは、ビット演算のプロセスをシミュレートし
、行列の位置a [i] [j]の数値をバイナリの01シーケンスに変換します。num [i] [k]配列を使用して、i番目の数値をバイナリで記録します。そして、j番目の数のk番目の位置a [i] [j]が1の2進位置に対応する場合、シーケンスのi番目の数とj番目の数の2進位置は1と0でなければならないことがわかります。これらの2つの数値のこのビットが0になるようにして、得られる答えが最小の辞書式順序になるようにします。
最後に、num配列に格納されている2進数を整数に変換し、それらを回答配列の出力に入れます。

#include <iostream>
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN = 1e3+7;
int num[MAXN][27];
int a[MAXN][MAXN];
int ans[MAXN];

string sw(int x)//把矩阵相应位置变成二进制
{
    
    
    string s = "";
    while(x)
    {
    
    
        s = s+char('0'+x%2);
        x = x/2;
    }
    return s;
}

int main()
{
    
    
    int n;
    cin>>n;
    for(int i = 1;i <= n;i ++)
    {
    
    
        for(int j = 1;j <= n;j ++)
        {
    
    
            scanf("%d",&a[i][j]);
            if(a[i][j] && j > i)//只有当一的时候 这个数对应的两个数相应位置上才为一
            {
    
    
                string s = sw(a[i][j]);
                for(int k = 0;k < s.size();k ++)
                {
    
    
                    if(s[k] == '1')// 如果不是1的话就当两个都是0 最后得出的就一定是最小的
                    {
    
    
                        num[i][k] = num[j][k] = 1;
                    }
                }
            }
        }
    }
    for(int i = 1;i <= n;i ++)
    {
    
    
        int tmp = 0;
        for(int j = 0;j < 27;j ++)
        {
    
    
            if(num[i][j] == 1)
                tmp += 1<<j;// 存储的时候就是反着存的所以最后直接这样就可以
        }
        ans[i] = tmp;
    }
    for(int i = 1;i <= n;i ++)
    {
    
    
        if(i != n)
            cout<<ans[i]<<" ";
        else
            cout<<ans[i]<<endl;
    }
    return 0;
}

おすすめ

転載: blog.csdn.net/weixin_45672411/article/details/105011898