洛谷 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
思路:
  第一步:在最外层循环枚举初始的每一列当做目标状态的第一列
  第二步:在每层循环中比较当前这列和目标状态的第一列的同行的数,如果不相同则把初始的那一行翻转
  第三步:看看剩下的列是否可以一一对应,如果可以就yes,不可以就继续枚举。
错因:行列弄反了好几次,调了很久。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int k,n,m,flag,num;
int sum1[110],sum2[110];
bool vised[110];
int ed[110][110],be[110][110],map[110][110];
int main(){
    scanf("%d",&k);
    while(k--){
        flag=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&map[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(vised,0,sizeof(vised));
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    be[i][j]=map[i][j];
            for(int i=1;i<=n;i++)
                if(be[i][k]!=ed[i][1])
                    for(int j=1;j<=m;j++)
                        be[i][j]=!be[i][j];
            vised[1]=1;num=1;
            for(int i=1;i<=m;i++)
                if(i!=k)
                    for(int j=2;j<=m;j++)
                        if(!vised[j]){
                            int ok=0;
                            for(int k=1;k<=n;k++)
                                if(ed[k][j]!=be[k][i]){
                                    ok=1;
                                    break;
                                }
                            if(ok)    continue;
                            else vised[j]=1,num++;
                        }
            if(num==m){
                cout<<"YES"<<endl;
                flag=1;break;
            }
        }
        if(!flag)    cout<<"NO"<<endl;
    }
}

posted @ 2017-09-25 22:14  一蓑烟雨任生平  阅读(280)  评论(0编辑  收藏  举报