ACM: uva 11464

来源:互联网 发布:电脑网络连接显示未知 编辑:程序博客网 时间:2024/05/17 15:56

D

EvenParity

Input: Standard Input

Output: Standard Output

ACM: <wbr>uva <wbr>11464

We have a grid of size N x N. Each cell of the grid initiallycontains a zero(0) or a one(1).
The parity of a cell is the number of 1s surrounding thatcell. A cell is surrounded by at most 4 cells (top, bottom, left,right).

Suppose we have a grid of size4 x 4

1

0

1

0

The parity of each cell wouldbe

1

3

1

2

1

1

1

1

2

3

3

1

0

1

0

0

2

1

2

1

0

0

0

0

0

1

0

0

 

 

 

For this problem,you have to change some of the 0s to 1s so that the parity of everycell becomes even. We are interested in the minimum number oftransformations of 0 to 1 that is needed to achieve the desiredrequirement.

Input

The first line of input is an integerT(T<30)that indicates the number of test cases. Each case starts with apositive integer N(1≤N≤15).Each of the next N linescontain Nintegers (0/1)each. The integers are separated by a single space character.

Output

For each case,output the case number followed by the minimum number oftransformations required. If it's impossible to achieve the desiredresult, then output -1 instead

Sample Input

3
3
0 0 0
0 0 0
0 0 0
3
0 0 0
1 0 0
0 0 0
3
1 1 1
1 1 1
0 0 0

Output for Sample Input

Case 1: 0
Case 2: 3
Case 3: -1

题意: n*n的矩阵中,现在要使得每个格子的上下左右相加的元素和为偶数, 每个格子的元素

         只能时0和1, 并且只有0元素可以改成1, 问用最少修改次数使得矩阵满足条件.


解题思路:

        1. 2^(15*15)这是枚举的情况, 可以采用动态规划中状态压缩的思路,枚举第一行的情况,

            然后根据第一行的情况推算出其它行的情况. 复杂度O( (2^15)*n*n ).


代码:

#include<cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 16
const int INF = (1<<29);

int n;
int a[MAX][MAX], b[MAX][MAX];

inline int min(int a, int b)
{
    return a< b ? a: b;
}

int solve(int situation)
{
    memset(b, 0,sizeof(b));
    for(int i =0; i < n; ++i)
    {
       if(situation& (1<<i)) b[0][i] =1;
       elseif(a[0][i] == 1) return INF;
    }
   
    for(int i =1; i < n; ++i)
    {
       for(int j =0; j < n; ++j)
       {
          int sum =0;
          if(i> 1) sum += b[i-2][j];
          if(j< n-1) sum += b[i-1][j+1];
          if(j> 0) sum += b[i-1][j-1];
          b[i][j] =sum%2;
          if(a[i][j]== 1 && b[i][j] == 0) returnINF;
       }
    }
   
    int count =0;
    for(int i =0; i < n; ++i)
       for(int j =0; j < n; ++j)
          if(a[i][j]!= b[i][j])
            count++;
    returncount;
}

int main()
{
//   freopen("input.txt", "r", stdin);
    int caseNum,num = 1;
    scanf("%d",&caseNum);
   while(caseNum--)
    {
       scanf("%d",&n);
       for(int i =0; i < n; ++i)
          for(int j =0; j < n; ++j)
             scanf("%d",&a[i][j]);
      
       int result =INF;
       for(int i =0; i < (1<<n);++i)
       {
          result =min(result, solve(i));
       }
      
       if(result ==INF) printf("Case %d: -1\n", num++);
       elseprintf("Case %d: %d\n", num++, result);
    }
    return0;
}

0 0
原创粉丝点击