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 }