题意:给出两个 n×mn \times m0101 矩阵 AABB,每行上往下依次编号为 1,2,,n1, 2, \dots, n,每列从左往右依次标号为 1,2,,m1,2,\dots,m。你每次可以选 AA 里面两个位置 (r1,c1)(r_1,c_1)(r2,c2)(1r1,r2n,1c1,c2m)(r_2,c_2) (1 \le r_1, r_2 \le n, 1 \le c_1, c_2 \le m),满足 r1=r2,c1c2=cr_1=r_2,|c_1-c_2|=c 或者 c1=c2,r1r2=rc_1=c_2,|r_1-r_2|=r,然后你可以这两个位置上的数字取反(11 变成 0000 变成 11)。问能否从 AA 变成 BB

这道题居然用了一个非正解的模拟过了

很明显,先把 AA 遍历一遍,如果遇到与 BB 不同的,就把同行的取反;

同理,再遍历一遍,这次把同列的取反。

这样我们就把整个 AA 遍历了一遍,最后再遍历一遍,看看与 BB 是否完全相同,输出即可。

正解解法:先考虑最简单的情况,仅有 cc 操作且 c=1c=1 。那么显然,只要数⼀数两个矩形每一行里面 11 的个数的奇偶性是否相同。
接下来考虑 rrcc 操作同时存在,且 r=c=1r=c=1。这个稍微分析下,也可以发现只要数⼀数两个矩形里面 11 的个数的奇偶性是否相同即可。
对于 r=2r=2 或者 c=2c=2,我们可以发现只要把奇数列,偶数列,奇数行,偶数行,拆分出来考虑,每个拆出来的小矩形都是⼀个 r=c=1r=c=1 的问题。

my code:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<string>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
int t;
int n,m,r,c;
string a[1010100],b[1010100];
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin>>t;
	while(t--)
	{
		bool flag=0;
		cin>>n>>m>>r>>c;
		for(int i=0;i<n;i++)
			cin>>a[i];
		for(int i=0;i<n;i++)
			cin>>b[i];
		for(int i=0;i+r<n;i++)
			for(int j=0;j<m;j++)
				if(a[i][j]!=b[i][j])
				{
					a[i][j]^=1;
					a[i+r][j]^=1;
				}//将不同的先用行变换
		for(int i=0;i<n;i++)
			for(int j=0;j+c<m;j++)
				if(a[i][j]!=b[i][j])
				{
					a[i][j]^=1;
					a[i][j+c]^=1;
				}//再用列变换
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				flag|=(a[i][j]!=b[i][j]);//在计算还有没有不同的
		cout<<(flag?"No":"Yes")<<endl;
	}
	return 0;
}

correct code:

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define SZ(x) ((int)x.size())
#define L(i,u) for (register int i=head[u]; i; i=nxt[i])
#define rep(i,a,b) for (register int i=(a); i<=(b); i++)
#define per(i,a,b) for (register int i=(a); i>=(b); i--)
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef pair<int,int> Pii;
typedef vector<int> Vi;
template<class T> inline void read(T &x){
	x=0; char c=getchar(); int f=1;
	while (!isdigit(c)) {if (c=='-') f=-1; c=getchar();}
	while (isdigit(c)) {x=x*10+c-'0'; c=getchar();} x*=f;
}
template<class T> inline void umin(T &x, T y){x=x<y?x:y;}
template<class T> inline void umax(T &x, T y){x=x>y?x:y;}
inline ui R() {
	static ui seed=416;
	return seed^=seed>>5,seed^=seed<<17,seed^=seed>>13;
}
int n,m,r,c,A[1000030],tot,s[3][3];
int main() {
	int T;read(T);while(T--){
		read(n);read(m);read(r);read(c);memset(s,0,sizeof(s));
		rep(i,1,n){
			static char t[1002000];scanf("%s",t+1);
			rep(j,1,m){int x=t[j]-'0';s[i%r][j%c]^=x;}
		}
		rep(i,1,n){
			static char t[1002000];scanf("%s",t+1);
			rep(j,1,m){int x=t[j]-'0';s[i%r][j%c]^=x;}
		}
		bool ok=1;
		rep(i,0,r-1)rep(j,0,c-1)ok&=!s[i][j];
		printf("%s\n",ok?"Yes":"No");

	}
	return 0;
}