玩过俄罗斯方块?那你知道俄罗斯方块共有七种吧(其实只有五种)
给一个黑白图,每次能将某些区域的格子黑白反转,至于某些区域的意思嘛,就是俄罗斯方块形状的区域咯(可水平翻转、上下翻转、旋转)
求能否将图变成全白
Input
多组数据,第一行一个正整数 T,表示数据组数 每组数据中第一行两个正整数 n,m,表示图的长和宽 接下来 n 行,每行 m 个数字,表示第 i 行第 j 列的格子的颜色,0为白,1为黑 T<=1000,∑n*m<=10000000
Output
对于每组数据,若能将图变成全白,则输出一行字符串"Yes",否则输出"No"(不包含双引号)
Input示例
1 4 4 0110 0110 1111 1111
Output示例
Yes
————————————————————————————————————————————————————————————————————————————————
这道题呢 我们可以靠一个 2x2 的矩阵将所有的 1 都转换到最后一行 和 最后一列
然后靠 1x4 将所有的一转换到最后一列 和 最下面一列 的三各
最后用 7 形状的 把问题转换成 右下角的三个格
最后发现偶数有解 奇数无解
在这个过程中我们又发现最后的奇偶 和 原来矩阵的 奇偶一样 这个就自己证明把
当然 1x? 和 2x2 需要特判一波
#include<stdio.h> #include<cstring> #include<algorithm> using namespace std; const int M=10000007; int read(){ int ans=0,f=1,c=getchar(); while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();} while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();} return ans*f; } int ans,T,n,m; bool s[M]; char c; bool isdigit(char c) {return c>='0' && c<='9';} int main() { T=read(); while(T--){ n=read(); m=read(); if(n>m) swap(n,m); while (!isdigit(c=getchar())); if (n==1){ for (int i=1;i<m;i++) {s[i]=(c-'0'); while(!isdigit(c=getchar()));} s[m]=(c-'0'); for (int i=1;i<=m-3;i++) if(s[i]) for(int j=0;j<=3;j++) s[i+j]^=1; if (s[m-2]||s[m-1]||s[m]) printf("No "); else printf("Yes "); } else if (n==2&&m==2){ int ans=0; for (int i=1;i<4;i++){ ans+=(c-'0'); while (!isdigit(c=getchar())); } ans+=(c-'0'); if(ans==4||!ans) printf("Yes "); else printf("No "); } else{ int ans=0; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) { if (i==n&&j==m) break; ans+=(c-'0'); while (!isdigit(c=getchar())); } ans+=(c-'0'); if (ans%2) printf("No "); else printf("Yes "); } } return 0; }