【思维】uva11464 Even Parity 偶数矩阵

题目链接
题目描述:对一个 nn(1<=n<=15) 01矩阵,把尽量少的0变成1,使得每个元素四周元素之和为偶数。求最少操作次数。

由于通过上一行就能确定下一行,那么只需要枚举第一行的01情况就可以递推出每一行了。
n范围小,可以将第一行的情况压缩为一个int范围的数(状态压缩)。

附AC代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAXN 20
#define INF 2147483647
using namespace std;

int map[MAXN][MAXN] ,ans ,n ,sum ;
int flag[MAXN][MAXN] ;

int check(int s)
{
    memset(flag,0,sizeof flag);
    for(int i=0;i<n;++i)
        if(s&(1<<i))flag[0][i]=1;
        else if(map[0][i])return INF;
    for(int i=0;i<n-1;++i)
        for(int j=0;j<n;++j)
        {
            sum=0;
            if(j>0)sum+=flag[i][j-1];
            if(j<n-1)sum+=flag[i][j+1];
            if(i>0)sum+=flag[i-1][j];
            if(sum&1)
                flag[i+1][j]=1;
            else
            {
                if(map[i+1][j]==1)return INF;
                flag[i+1][j]=0;
            }
        }
    int cnt=0 ;
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j)
            if(map[i][j]!=flag[i][j])
                ++cnt;
    return cnt;
}

int main()
{
    int T ,cas=0 ;
    scanf("%d",&T );
    while(T--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;++i)
            for(int j=0;j<n;++j)
                scanf("%d",&map[i][j]);
        ans=INF;
        for(int s=0;s<(1<<n);++s)
            ans=min(ans,check(s));
        printf("Case %d: ",++cas);
        if(ans==INF)
            puts("-1");
        else printf("%d\n",ans);
    }
    return 0;
}

你可能感兴趣的:(uva11464)