1. 程式人生 > >洛谷 P1275 魔板

洛谷 P1275 魔板

lag 任務 中間 %d tool ack ise sca ref

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; } }






洛谷 P1275 魔板