贪心
首先用 $a$ 中的每个元素和 $b$ 中的每个元素异或得到新的矩阵 $c$,$c_{i,j}$ 的意义为是否要操作奇数次 $a_{i,j}$ 来得到 $b_{i,j}$,实际上只有操作 $1$ 次和操作 $0$ 次是本质不同的,奇数次操作等价于操作 $1$ 次,偶数次操作等价于操作 $0$ 次。
于是 $c_{i,j} = 1$ 说明这个位置要被操作一次,否则这个位置不能被操作。
对于第一行的元素 $c_{1,i}$,如果 $c_{1,i} = 1$ 就操作一次第 $i$ 列。
对于第 $2 \sim n$ 行,由于第一行已经固定,不能操作列,只能操作整行,如果操作这一行和不操作这一行都不满足要求,那么问题无解。
时间复杂度 $O(n^2)$。
#include<bits/stdc++.h>
using namespace std;
char a[1'005][1'005],b[1'005][1'005];
int n,c[1'005][1'005];
void solution(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%s",a[i]+1);
for(int i=1;i<=n;i++) scanf("%s",b[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) c[i][j]=(a[i][j]!=b[i][j]);
for(int i=1;i<=n;i++) if(c[1][i])
for(int j=1;j<=n;j++) c[j][i]^=1;
for(int i=2;i<=n;i++) if(c[i][1])
for(int j=1;j<=n;j++) c[i][j]^=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) if(c[i][j]) return puts("No"),void();
puts("Yes");
}
int T;
int main(){
scanf("%d",&T);
while(T--) solution();
return 0;
}