Atcoder
题解
]
ARC199A Flip Row or Col 2
先操作若干列使得第一行全部变成 $0$。
因为 $r_1<n/4$,因此我们只能修改不超过 $n/4$ 次列。
如果第 $i$ 行 $1$ 的数量超过 $n/2$,则必须翻转该行才可能在修改不超过 $n/4$ 次列时满足 $r_i<n/4$。
以上条件均为必要条件,所以全部做完还要再 check 一遍。
#include<bits/stdc++.h>
#define siz(x) int((x).size())
#define all(x) std::begin(x),std::end(x)
#define fi first
#define se second
using namespace std;
using unt=unsigned;
using loli=long long;
using lolu=unsigned long long;
using pii=pair<int,int>;
mt19937_64 rng(random_device{}());
constexpr int N=1007;
int n,a[N][N],r[N],c[N],b1[N],b2[N];
bool solve(){
cin>>n;
for(int i=1;i<=n;i++){
string s;cin>>s;
b1[i]=b2[i]=0;
for(int j=1;j<=n;j++)
a[i][j]=s[j-1]-'0';
}
for(int i=1;i<=n;i++)cin>>r[i];
for(int i=1;i<=n;i++)cin>>c[i];
for(int i=2;i<=n;i++){
int cnt=0;
for(int j=1;j<=n;j++)
cnt+=(a[1][j]!=a[i][j]);
if(cnt>n/2){
b1[i]=1;
for(int j=1;j<=n;j++)
a[i][j]=!a[i][j];
}
}
for(int j=1;j<=n;j++){
int cnt=0;
for(int i=1;i<=n;i++)
cnt+=a[i][j];
if(cnt!=c[j]){
if(n-cnt!=c[j])
return false;
b2[j]=1;
for(int i=1;i<=n;i++)
a[i][j]=!a[i][j];
}
}
for(int i=1;i<=n;i++){
int cnt=0;
for(int j=1;j<=n;j++)
cnt+=a[i][j];
if(cnt!=r[i])
return false;
}
return true;
}
signed main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
ios::sync_with_stdio(false);cin.tie(nullptr);
int T;cin>>T;while(T--){
if(!solve())cout<<"No\n";
else{
cout<<"Yes\n";
for(int i=1;i<=n;i++)cout<<b1[i];
cout<<'\n';
for(int i=1;i<=n;i++)cout<<b2[i];
cout<<'\n';
}
}
return 0;
}