UVA11464 Even Parity
思路
发现第一行确定之后,剩下的都可以唯一确定
所以\(2^n\)枚举第一行,再检查即可
复杂度\(O(2^n n^2)\)
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,mat[20][20],my_mat[20][20],ans=0x3f3f3f3f;
int get_sum(int i,int j){
return my_mat[i][j-1]+my_mat[i-1][j]+my_mat[i][j+1];
}
int check(int t){
for(int i=0;i<n;i++)
my_mat[1][i+1]=((t>>i)&1);
for(int i=2;i<=n;i++)
for(int j=1;j<=n;j++)
my_mat[i][j]=get_sum(i-1,j)%2;
// printf("\n\n");
// for(int i=1;i<=n;i++){
// for(int j=1;j<=n;j++)
// printf("%d ",my_mat[i][j]);
// printf("\n");
// }
// printf("\n\n");
int ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
if(my_mat[i][j]==1&&mat[i][j]==0)
ans++;
else if(my_mat[i][j]==0&&mat[i][j]==1)
return -1;
if((my_mat[i-1][j]+my_mat[i+1][j]+my_mat[i][j-1]+my_mat[i][j+1])%2)
return -1;
}
return ans;
}
int main(){
// freopen("test.in","r",stdin);
// freopen("test.out","w",stdout);
int T,cnt=0;
scanf("%d",&T);
while(T--){
cnt++;
memset(my_mat,0,sizeof(my_mat));
ans=0x3f3f3f3f;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&mat[i][j]);
for(int i=0;i<(1<<n);i++){
int t=check(i);
if(t!=-1)
ans=min(ans,t);
}
if(ans==0x3f3f3f3f)
printf("Case %d: -1\n",cnt);
else
printf("Case %d: %d\n",cnt,ans);
}
return 0;
}