题解:P10635 BZOJ3517 翻硬币
写在前面:我不太会写题解,写出来的东西都是一坨一坨的,但是已经尽量清晰的描述了,请谅解。
考虑如何使用一些操作来只翻转一位。
当我们轮流对
- 对于
x\neq x_0 且y\neq y_0 的(x,y) ,它仅会被(x,y_0) 和(x_0,y) 操作到,操作两次相当于没变; - 对于
x=x_0 和y=y_0 只有一个满足的(x,y) ,它会被所有(x_0,i) 或所有(i,y_0) 操作到,而n 为偶数,所以也不变; - 对于
x=x_0 且y=y_0 的(x,y) ,它会被每一次操作影响到,总共2n-1 次,为奇数,所以会变化。
所以,我们发现这样操作之后,我们能够仅翻转
显然的,我们能够通过多次进行这样的轮流操作来翻转任意格子。如果某一个格子操作了两次则相当于没有操作,这样我们可以把每个格子上进行的操作次数限制成
于是,操作后的翻转情况(格子的被操作情况)有
首先考虑怎么把
而从
实现很简单。
cin>>n;
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){
cin>>ch[i][j];
if(ch[i][j]=='1')++r[i],++c[j];
}
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){
ans+=(ch[i][j]+r[i]+c[j])&1;
}
cout<<min(ans,n*n-ans)<<"\n";