【BZOJ】3517: 翻硬币-异或方程组

本文探讨了一个关于二维数组中硬币翻转的问题,并通过异或运算求解最优方案。利用给定条件推导出翻转操作的数学模型,最终通过简洁的C++代码实现了算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意

坑啊
设a(i,j)表示第i行,第j列的位置上是否需要翻一次,x(i,j)表示i,j这个位置的硬币是否需要翻。
先假设都要翻为0.
那么
a(i,1) xor a(i,2) xor ... xor a(i,n1) xor a(i,n) xor a(1,j) xor a(2,j) xor ... xor a(i1,j) xor a(i+1,j) xor ... xor a(n1,j) xor a(n,j) = x(i,j)a(i,1) xor a(i,2) xor ... xor a(i,n−1) xor a(i,n) xor a(1,j) xor a(2,j) xor ... xor a(i−1,j) xor a(i+1,j) xor ... xor a(n−1,j) xor a(n,j) = x(i,j)
故:
a(i,j)=a(i,1) xor ... xor a(i,j1) xor a(i,j+1) xor ... xora(i,n) xor a(1,j) xor... xor a(i1,j) xor a(i+1,j) xor ... xor a(n1,j) xor a(n,j) xor x(i,j)a(i,j)=a(i,1) xor ... xor a(i,j−1) xor a(i,j+1) xor ... xora(i,n) xor a(1,j) xor... xor a(i−1,j) xor a(i+1,j) xor ... xor a(n−1,j) xor a(n,j) xor x(i,j)
由于n为偶数,各项消掉后得
a(i,j)=x(i,1) xor ... xor x(i,n) xor x(1,j) xor ... xor x(i1,j) xor x(i+1,j) xor x(n,j)a(i,j)=x(i,1) xor ... xor x(i,n) xor x(1,j) xor ... xor x(i−1,j) xor x(i+1,j) xor x(n,j)
翻为1就是n*n-sum(a(i,j)),两者取个min即可


代码

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1001;
int n,a[N][N],x[N][N],r[N],l[N],as[3];
char s[N];
int main(){
    int i,j;
    scanf("%d",&n);
    for(i=1;i<=n;++i){
      scanf("%s",s);
      for(j=1;j<=n;++j){
        a[i][j]=s[j-1]-'0';
        r[i]^=a[i][j];
        }   
    }
    for(i=1;i<=n;++i)
     for(j=1;j<=n;++j) 
      l[i]^=a[j][i];
    for(i=1;i<=n;++i)
     for(j=1;j<=n;++j) 
      as[l[j]^r[i]^a[i][j]]++;
    if(as[0]<as[1]) printf("%d\n",as[0]);
    else printf("%d\n",as[1]);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值