CF486B

扯在前面

本人找规律找了很长时间,然后发现找到规律之后其实是lj题,于是五分钟敲完代码,然后WA了两发

正文

题意:

A, B 都是 n*m 的 01 矩阵,已知 B 矩阵是由A矩阵以一种规则生成

Bij 是由 A 矩阵的第 i 行行的所有元素和第 j 列列的所有元素进行 或运算 得到

给定B矩阵,求是否存在一个矩阵A能被合理生成;

不懂的同学可以先了解一下或运算

传送门


分析:

因为我们已知以下关系且每次参与运算的是一整行和一整列的所有数

0|0=0;  0|1=1;  1|0=1;  1|1=1;

所以

  • 当某个位置只要出现一个零,那么他对应矩阵所在的整行或整列如果是零都会是零,因为只要出现一个一,他就不可能是零;
  • 这样的话当然我们也会知道知道,当某行或某列出现一个一时,那他的整行整列必定会出现至少一个一,因为只要有一参与或运算就会是一

做法

知道这两个结论之后我们就可以用简单的方法做题了

根本不用或运算符|,而是另一种方法:

  1. 先把A矩阵赋值为只有1的矩阵,然后填零
  2. 当在B矩阵中找到某个位置是0时,就把A矩阵对应的整行整列都赋值成0
  3. 当在B矩阵中找到某个位置是1时,就查看一下A矩阵对应的行与列是否有1,若没有则为NO
  4. 剩下的输出YES

代码

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring> 
#include<cmath>
#include<algorithm>
#define maxn 500
using namespace std;
int n,m,b[maxn][maxn],a[maxn][maxn];
int cnt;
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            a[i][j]=1;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            cin>>b[i][j];
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(b[i][j]==0){
                for(int k=1;k<=n;k++)
                    a[k][j]=0;
                for(int k=1;k<=m;k++)
                    a[i][k]=0;
            } 
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(b[i][j]==1){
                for(int k=1;k<=n;k++)
                    if(a[k][j]==1){
                        cnt++;
                        break;
                    }
                for(int k=1;k<=m;k++)
                    if(a[i][k]==1){
                        cnt++;
                        break;
                    }
                if(cnt==0){
                    cout<<"NO";
                    return 0;
                }
            }
        }
    }
    cout<<"YES"<<endl;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
            cout<<a[i][j]<<" ";
        cout<<endl;
    }
    return 0;
} 

制作不易,请各位批评指正

原文地址:https://www.cnblogs.com/KnightL/p/13935422.html