题目:Even Parity
思路:
枚举第一行,根据前两行(第二行由第一行和全0的第零行计算)的数据计算出后面的数。
要用到位运算。
注意:
1、位运算的优先级。
2、在我的程序中,枚举的数据和输入的顺序是倒着的。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <cstring>
#include <map>
using namespace std;
#define maxn 15
#define ll long long
int n;
int a[maxn+5][maxn+5];
int find(int i,ll x){
int s=0;
for(int j=1;j<=n;j++){
s+=((x&1)^a[i][j]);
x>>=1;
}
return s;
}
bool judge(int i,ll x){
for(int j=1;j<=n;j++){
int y=x&1;
x>>=1;
if(y==0&&a[i][j]==1) return false;
}
return true;
}
int main() {
int T;
scanf("%d",&T);
for(int t=1;t<=T;t++) {
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
scanf("%d",&a[i][j]);
}
}
ll m=1<<n;
int sum=(1<<30);
for(ll i=0;i<m;i++){ //枚举第一排
if(!judge(1,i)) continue;
int ans=0;
ans+=find(1,i);
ll grdfa=0; //上上牌
ll fa=i; //上排
for(int j=2;j<=n;j++){ //第j排
ll x=0; //第j排压缩后
for(int k=n;k>=1;k--){ //第k列
int y=((grdfa>>k-1)+(fa>>k-2)+(fa>>k))&1;
x<<=1,x+=y;
ans+=y^a[j][k];
}
if(!judge(j,x)) {
ans=(1<<30);
break;
}
grdfa=fa,fa=x;
}
sum=min(sum,ans);
}
if(sum==(1<<30)) sum=-1;
printf("Case %d: %d\n",t,sum);
}
return 0;
}