1. 程式人生 > >uva 11464 偶數矩陣 (二進位制表示法)

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;
}