EOJ mouthly 2020.3 B 与矩阵

在这里插入图片描述学习了一下别人的题解 以后要加强位运算的理解啊

emmmm 模拟一下位运算的过程
把矩阵a[i][j]位置上的数转换为二进制情况下的01序列 用一个num[i][k]数组 来记录第i个数二进制下的第k为 和 第j个数的第k位 当a[i][j]对应二进制位上为1可以知道数列中第i个数和第j个数的二进制位置上一定为1 为零的情况下 我们就让这两个数这个位上都为0这样就可以保证得到的答案是字典序最小的
最后把num数组存下来的二进制数转换成整数 放入答案数组 输出即可

#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