题意:给出一个n*n的 0、1矩阵,把尽量少的0改成1,使得每个元素的上下左右的元素之和都为偶数。

思路:约束条件是某元素周围上下左右四个元素之和必须为偶数,那么,只需要枚举第一行,剩下的n-1行根据前一行递推出来。

话说最近改了一下代码风格,盗用了某大神的define和template。。。下面代码就不贴那部分了。

代码:

 1 const int maxn = 20;
 2 const int inf = 9999999;
 3 int mi;
 4 int n, a[maxn][maxn], b[maxn][maxn], c[maxn];
 5 
 6 int make(){
 7     int v;
 8     REP(i, n)
 9     b[0][i] = c[i];
10     FOR(i, 1, n)
11     REP(j, n){
12         v = b[i-2][j] + b[i-1][j-1] + b[i-1][j+1];
13         b[i][j] = (v&1);
14     }
15 }
16 
17 int cal(){
18     int res = 0;
19     REP(i, n)
20     REP(j, n){
21          if(a[i][j] == 1 && b[i][j] == 0)//和为偶数
22          return inf;
23          if(a[i][j] == 0 && b[i][j] == 1)//和为奇数
24          res++;
25     }
26     return res;
27 }
28 
29 void solve(int s){
30     if(s == n){
31         make();
32         checkmin(mi, cal());
33         return ;
34     }
35     c[s] = 0;
36     solve(s + 1);
37     c[s] = 1;
38     solve(s + 1);
39 }
40 
41 void init(){
42     mi = inf;
43     memset(b, 0, sizeof(b));
44 }
45 int main(){
46     #ifndef ONLINE_JUDGE
47         freopen("in.txt", "r", stdin);
48     #endif
49     int t, k = 0;
50     cin>>t;
51     while(t--){
52         init();
53         k++;
54         cin>>n;
55         REP(i,n)
56         REP(j,n)
57         scanf("%d", &a[i][j]);
58         printf("Case %d: ", k);
59         solve(0);
60         if(mi == inf) puts("-1");
61         else printf("%d\n",mi);
62     }
63     return 0;
64 }

 

 

posted on 2012-11-15 21:21  pony1993  阅读(780)  评论(0编辑  收藏  举报

View My Stats