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;
}
posted @ 2019-04-19 16:38  dreagonm  阅读(87)  评论(0编辑  收藏  举报