题意:有20个数字,0或1。如果改变一个数的状态,它左右两边的两个数的状态也会变反。问从目标状态到全0,至少需要多少次操作。

显然,问题可以从目标状态到全0 转化为 全0到目标状态。

于是可以列出方程组,每行一个数的状态。

为了知道操作次数,那么就要知道未知数为1有多少个,所以就要解方程组,解方程组就不得不枚举自由元了。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #define MAXN 20
 5 #define MAXM 25
 6 #define oo 0x7FFFFFFF
 7 using namespace std;
 8 int g[MAXM][MAXM], tmp[MAXM], x[MAXM];
 9 int ans;
10 bool Read() {
11     int i;
12     for (i = 0; i < MAXN; i++) {
13         if (scanf("%d", &g[i][MAXN]) == EOF)
14             return false;
15     }
16     return true;
17 }
18 int Cal() {
19     int i, j, k, cnt;
20     k = cnt = 0;
21     for (i = MAXN - 1; i >= 0; i--) {
22         if (g[i][i]) {
23             x[i] = g[i][MAXN];
24             for (j = i + 1; j < MAXN; j++)
25                 x[i] ^= x[j] && g[i][j];
26         } else
27             x[i] = tmp[k++];
28         if (x[i])
29             cnt++;
30     }
31     return cnt;
32 }
33 void DFS(int now, int cnt) {
34     if (cnt == 0)
35         ans = min(ans, Cal());
36     else {
37         tmp[now] = 0;
38         DFS(now + 1, cnt - 1);
39         tmp[now] = 1;
40         DFS(now + 1, cnt - 1);
41     }
42 }
43 void Gauss() {
44     int r, c, i, j;
45     for (c = r = 0; c < MAXN; c++, r++) {
46         for (i = r; i < MAXN; i++) {
47             if (g[i][c])
48                 break;
49         }
50         if (i >= MAXN)
51             r--;
52         else {
53             if (i != r) {
54                 for (j = 0; j <= MAXN; j++)
55                     swap(g[i][j], g[r][j]);
56             }
57             for (i = r + 1; i < MAXN; i++) {
58                 if (g[i][c]) {
59                     for (j = c; j <= MAXN; j++)
60                         g[i][j] ^= g[r][j];
61                 }
62             }
63         }
64     }
65     DFS(0, MAXN - r);
66 }
67 int main() {
68     int i;
69     while (Read()) {
70         for (i = 0; i < MAXN; i++) {
71             g[max(i - 1, 0)][i] = 1;
72             g[i][i] = 1;
73             g[min(MAXN - 1, i + 1)][i] = 1;
74         }
75         ans = oo;
76         Gauss();
77         printf("%d\n", ans);
78     }
79     return 0;
80 }
posted on 2012-09-03 09:38  DrunBee  阅读(239)  评论(0编辑  收藏  举报