UVa11464 Even Parity

  原题传送:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2459

  一般的想法是枚举每一个元素,那么会有2255种情况,显然无法承受。注意到约束条件是某元素周围上下左右四个元素之和必须为偶数,利用这个条件,我们可以轻松的在2255种情况中去掉不合法的情况而剩下合法的情况,并在这些合法的情况中选择最优的符合题目输入数据的情况。那么,只需要枚举第一行,由第一行可以推出第二行,进而第三行…第n行。直接深搜比较,复杂度O(2n*n2)。

View Code
 1 #include <stdio.h>
 2 #include <string.h>
 3 #define INF 0x3f3f3f3f
 4 #define N 20
 5 int n, g[N][N], p[N][N], a[N], min;
 6 
 7 void make()
 8 {
 9     int v, i, j;
10     for(i = 1; i <= n; i ++)
11         p[1][i] = a[i];
12     for(i = 2; i <= n; i ++)
13     {
14         for(j = 1; j <= n; j ++)
15         {
16             v = p[i - 2][j] + p[i - 1][j - 1] + p[i - 1][j + 1];
17             p[i][j] = ((v & 1) ? 1 : 0);
18         }
19     }
20 }
21 
22 int cal()
23 {
24     int i, j, cnt = 0;
25     for(i = 1; i <= n; i ++)
26     {
27         for(j = 1; j <= n; j ++)
28         {
29             if(g[i][j] == 1 && p[i][j] == 0)
30                 return INF;
31             if(g[i][j] == 0 && p[i][j] == 1)
32                 cnt ++;
33         }
34     }
35     return cnt;
36 }
37 
38 void dfs(int d)
39 {
40     if(d == n+1)
41     {
42         make();
43         int tmp = cal();
44         if(tmp < min)
45             min = tmp;
46         return ;
47     }
48     a[d] = 0;
49     dfs(d + 1);
50     a[d] = 1;
51     dfs(d + 1);
52 }
53 
54 int main()
55 {
56     int t, cas, i, j;
57     scanf("%d", &t);
58     for(cas = 1; cas <= t; cas ++)
59     {
60         scanf("%d", &n);
61         memset(p, 0, sizeof p);
62         for(i = 1; i <= n; i ++)
63             for(j = 1; j <= n; j ++)
64                 scanf("%d", &g[i][j]);
65                 
66         min = INF;
67         dfs(1);
68         if(min == INF)
69             printf("Case %d: %d\n", cas, -1);
70         else
71             printf("Case %d: %d\n", cas, min);
72     }
73     return 0;
74 }

 

你可能感兴趣的:(uva)