uva 11464 偶数矩阵 (二进制表示法)

题目大意:有一个N*N的01矩阵,你的任务是把尽量少的0变成1,(但不能将1变成0)以使得每个元素的上下左右的元素(若存在)均为偶数。

思路 : 如果暴力枚举每一个位置的话时间复杂度为 2 的255 次方,肯定不行 。但是如果只枚举第一行,其他下面几行都能够通过

上边的来固定是0还是1。时间复杂度就是 2的15次方 加2的n次方;

利用而二进制数来枚举每一种情况 00000 00000 00000 ~11111 11111 11111  (1<<15)

#include <iostream>
#include <cstring>

using namespace std;

int arr[16][16],brr[16][16];

const int inf=1e9+7;
int n;
int change(int s)
{
    memset(brr,0,sizeof(brr));         //不要忘了更新数组
    for(int i=0; i<n; i++)
    {
        if(s&(1<<i)) brr[0][i]=1;      //给第一行brr赋值,实际上是brr[][]的01顺序是的S的01 
                                       //相反的

        else if(arr[0][i]==1) return  inf;     //1不能变成0
    }
    

    for(int i=1;i<n;i++)
        for(int j=0;j<n;j++)
    {
        int sum=0;
        if(i>1) sum+=brr[i-2][j];
        if(j>0) sum+=brr[i-1][j-1];
        if(j<n) sum+=brr[i-1][j+1];

        brr[i][j]=sum%2;               //确定下一位是0 还是1 

        if(brr[i][j]==0&&arr[i][j]==1) return inf;

    }


    int cnt=0;
    for(int i=0;i<n;i++)
        for(int j=0;j<n;j++)
    {
        if(brr[i][j]!=arr[i][j])
        cnt++;
    }

    return cnt;
}
int main()
{
    int T;
    cin >>T;
    for(int t=1; t<=T; t++)
    {

        cin >>n;
        for(int i=0; i<n; i++)
            for(int j=0; j<n; j++)
                cin >>arr[i][j];

        int ans=inf;

        for(int i=0; i<(1<<n); i++)
        {
            int k=change(i);

            if(ans>k)
                ans=k;
        }
        
        if(ans!=inf)
        cout <<"Case "<<t<<": "<<ans<<endl;
        else
        cout <<"Case "<<t<<": "<<-1<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41199502/article/details/82799817