洛谷 P1275 魔板(模拟)

有这样一种魔板:它是一个长方形的面板,被划分成n行m列的n*m个方格。每个方格内有一个小灯泡,灯泡的状态有两种(亮或暗)。我们可以通过若干操作使魔板从一个状态改变为另一个状态。操作的方式有两种:

(1)任选一行,改变该行中所有灯泡的状态,即亮的变暗、暗的变亮;

(2)任选两列,交换其位置。

当然并不是任意的两种状态都可以通过若干操作来实现互相转化的。

你的任务就是根据给定两个魔板状态,判断两个状态能否互相转化。

输入输出格式

输入格式:

文件中包含多组数据。第一行一个整数k,表示有k组数据。

每组数据的第一行两个整数n和m。(0<n,m≤100)

以下的n行描述第一个魔板。每行有m个数字(0或1),中间用空格分隔。若第x行的第y个数字为0,则表示魔板的第x行y列的灯泡为“亮”;否则为“暗”。

然后的n行描述第二个魔板。数据格式同上。

任意两组数据间没有空行。

输出格式:

共k行,依次描述每一组数据的结果。

若两个魔板可以相互转化,则输出YES,否则输出NO。(注意:请使用大写字母)

输入输出样例

输入样例#1:

2
3 4
0 1 0 1
1 0 0 1
0 0 0 0
0 1 0 1
1 1 0 0
0 0 0 0
2 2
0 0
0 1
1 1
1 1

输出样例#1: 

YES
NO
/*

*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <bitset>
#include <stack>
#define ll long long
#define ull unsigned long long
#define inf 0x3f3f3f3f
const int mod=1000000007;
const int N=105;
using namespace std;
int mp[N][N],ed[N][N];
int aa[N][N];
int vis[N];
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int n,m;
        int flag=0,num;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                scanf("%d",&mp[i][j]);
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                scanf("%d",&ed[i][j]);
        for(int k=1; k<=m; k++)//枚举每一列
        {
            memset(vis,0,sizeof(vis));
            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                    aa[i][j]=mp[i][j];
            for(int i=1; i<=n; i++)
            {
                if(aa[i][k]!=ed[i][1])//每一列都和目标状态的第一列比较,不一样就0 1 转换
                {
                    for(int j=1; j<=m; j++)
                        aa[i][j]=!aa[i][j];
                }
            }
            vis[1]=1;
            num=1;
            for(int i=1; i<=m; i++)
            {//遍历aa所有列,比较剩余的和目标是不是完全匹配
                if(i!=k)
                {   int f=0;
                    for(int j=2; j<=m; j++)//遍历目标状态的除第一列以外的列
                    {
                        if(!vis[j])
                        {
                            int ok=0;
                            for(int h=1; h<=n; h++)//行
                            {
                                if(ed[h][j]!=aa[h][i])//有不匹配的
                                {
                                    ok=1;
                                    break;
                                }
                            }
                            if(ok)
                                continue;
                            else//有匹配的
                            {
//                                f=1;
                                vis[j]=1,num++;
                            }

                        }
//                        if(f)
//                            break;
                    }
                }
            }
            if(m==num)
            {
                printf("YES\n");
                flag=1;
                break;
            }
        }
        if(!flag)
            printf("NO\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Kuguotao/article/details/89371611