Codeforces Round #697 (Div. 3) F. Unusual Matrix

链接

https://codeforces.com/contest/1475/problem/F

题意

有两个矩阵 $a,b$,现在可以将矩阵 $a$ 某一行或某一列的元素异或 $1$。

可操作无限次,问能否将矩阵 $a$ 转化为矩阵 $b$?

思路

对于某一行或某一列进行两次操作等同于没有操作,所有对于某一行或某一列的操作数只有 $0/1$ 次。

枚举第一行操作了 $0/1$ 次。

确认了第一行的操作次数,那么我们可以通过比较 $a,b$ 的第一行,确认第 $1 \sim n$ 列的操作次数。

确认了第一列的操作次数,我们可以通过比较 $a,b$ 的第一列,确认第 $2 \sim n$ 行的操作次数。

然后逐一比较 $a,b$ 中的每个元素,判断经过行列操作后是否相同。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <bits/stdc++.h>
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(),(x).end()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define FI first
#define SE second
using namespace std;
typedef double DB;
typedef long double LD;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PII;
typedef vector<int> VI;
typedef vector<PII> VPII;
//head
const int N=1e3+5;
int n,a[N][N],c[N],r[N];
string s;
bool check() {
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if((r[i]+c[j]+a[i][j])&1)
return false;
return true;
}
int main() {
//freopen("E:/OneDrive/IO/in.txt","r",stdin);
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin>>T;
while(T--) {
cin>>n;
for(int i=1;i<=n;i++) {
cin>>s;
for(int j=1;j<=n;j++) a[i][j]=s[j-1]-'0';
}
for(int i=1;i<=n;i++) {
cin>>s;
for(int j=1;j<=n;j++) a[i][j]^=s[j-1]-'0';
}
r[1]=0;
for(int i=1;i<=n;i++) c[i]=a[1][i];
for(int i=2;i<=n;i++) r[i]=c[1]^a[i][1];
if(check()) cout<<"YES"<<'\n';
else {
r[1]=1;
for(int i=1;i<=n;i++) c[i]=1^a[1][i];
for(int i=2;i<=n;i++) r[i]=c[1]^a[i][1];
if(check()) cout<<"YES"<<'\n';
else cout<<"NO"<<'\n';
}
}
return 0;
}