BZOJ[3517] 翻硬币

 这个题...就算解不了异或方程组也是要写一写式子的

   行列都是偶数也应该是异或偶数次能消掉的提示

   那么假设当前的目标状态是把所有的点都变成0;

   设X[i][j]为这个点有没有被操作;

   那么对于一个点列出出来的方程就是这个点所在行,列所有点的X值在异或他的初始状态为0,然后把这行    这列所有点的方程异或起来,就能神奇的发现,随后就只剩下X[i][j]没有异或掉(因为行数,列数都是偶        数),然后x[i][j]就等于其所在行,列的原状态异或起来,然后统计有多少X[i][j]的值为1,就是变为零的方     案,然后原来操作的点都不操作,不操作的点都操作就是边成1的,ans=min(cnt,n*n-cnt);

  Code

  

 1 #include <cmath>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <algorithm>
 7 # define maxn 1010
 8 using namespace std;
 9 int n;
10 int sum1[maxn],sum2[maxn],Num[maxn][maxn],X[maxn][maxn];
11 char s[maxn];
12 int main(){
13     // freopen("a.in","r",stdin);
14     scanf("%d",&n);
15     for(int i=1;i<=n;i++){
16         scanf("%s",&s);
17         for(int j=0;j<n;j++)
18             Num[i][j+1]=s[j]-'0';
19     }
20     for(int i=1;i<=n;i++)
21         for(int j=1;j<=n;j++)
22             sum1[i]^=Num[i][j];
23     for(int j=1;j<=n;j++)
24         for(int i=1;i<=n;i++)
25             sum2[j]^=Num[i][j];
26     int cnt=0;
27     for(int i=1;i<=n;i++){
28         for(int j=1;j<=n;j++){
29             X[i][j]=sum1[i]^sum2[j]^Num[i][j];
30             if(X[i][j]) cnt++;
31             // cout<<X[i][j];
32         } 
33         // cout<<endl;
34     }
35     cnt=min(cnt,n*n-cnt);
36     cout<<cnt<<endl;
37 }
View Code

 

原文地址:https://www.cnblogs.com/FOXYY/p/7664958.html