他人の解決策を研究した後、ビット操作の理解を深める必要があります。
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;
}