UVa11464 Even Parity

D

Even Parity

Input: Standard Input

Output: Standard Output

 

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

Suppose we have a grid of size 4 x 4: 

 

1

0

1

0

The parity of each cell would be

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 every cell becomes even. We are interested in the minimum number of transformations of 0 to 1 that is needed to achieve the desired requirement.

 
Input

The first line of input is an integer T (T<30) that indicates the number of test cases. Each case starts with a positive integer N(1≤N≤15). Each of the next N lines contain N integers (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 of transformations required. If it's impossible to achieve the desired result, then output -1 instead.

 

Sample Input                             Output for 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
 

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


Problem Setter: Sohel Hafiz,

Special Thanks: Derek Kisman, Md. Arifuzzaman Arif

题目大意:给定一个N*N的正方形网格,每个网格里都有一个数字,要么是0,要么是1。要求你让尽量少的数字为0的格子变成1,使得每一个格子相邻的四个格子(如果存在的话)的数值和等于偶数。

题解:此道题目和Fill the Square有点相似,所以直接想到了枚举。我们只需枚举矩阵的第一行即可,只要第一行确定了,我们就可以计算出出第二行,计算出第二行之后我们又可以计算出第三行。。。依次类推即可。为什么呢?因为对于一个位置为(i,j)的格子,他肯定是(i-1,j)相邻的格子,而在计算(i,j)的时候,格子(i-1,j)的另外三个相邻的格子是已经确定了的,因此也就确定了格子(i,j)的数值。注意初始化和边界!!!!(果断各被坑一次)

View Code
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #include<math.h>
 5 #define MAXN 20
 6 #define INF 0x7fffffff
 7 int a[MAXN][MAXN],goal[MAXN][MAXN];
 8 int n;
 9 long min(long a,long b)
10 {
11     return a>b?b:a;
12 }
13 long check(long s)
14 {
15     long i,j,sum,ans;
16     memset(goal,0,sizeof(goal));
17     for(i=0; i<n; i++)
18     {
19         if(s&(1<<i))
20             goal[0][i]=1;
21         else if(a[0][i]==1) return INF;
22     }
23     for(i=1; i<n; i++)
24         for(j=0; j<n; j++)
25         {
26             sum=0;
27             if(i-2>=0) sum+=goal[i-2][j];
28             if(j-1>=0) sum+=goal[i-1][j-1];
29             if(j+1<n)sum+=goal[i-1][j+1];
30             goal[i][j]=sum%2;
31             if(a[i][j]==1&&goal[i][j]==0) return INF;
32 
33         }
34     ans=0;
35     for(i=0; i<n; i++)
36         for(j=0; j<n; j++)
37             if(a[i][j]!=goal[i][j]) ans++;
38     return ans;
39 }
40 int main(void)
41 {
42     long t,i,j,p;
43     long ans;
44     scanf("%ld",&t);
45     p=0;
46     while(t--)
47     {
48         scanf("%d",&n);
49         ans=INF;
50         for(i=0; i<n; i++)
51             for(j=0; j<n; j++)
52                 scanf("%d",&a[i][j]);
53         for(i=0; i<(1<<n); i++)
54             ans=min(ans,check(i));
55         if(ans==INF)
56             printf("Case %ld: -1\n",++p);
57         else
58             printf("Case %ld: %ld\n",++p,ans);
59     }
60     return 0;
61 }

 

原文地址:https://www.cnblogs.com/zjbztianya/p/2973562.html