SOJ 1171. The Game of Efil

解题技巧:

  1.地图扩展expand().

  2.目标状态压缩。

代码如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 using namespace std;
 4 
 5 const int maxm = 18;
 6 const int maxn = 18;
 7 int m, n;
 8 
 9 int dm[8] = {-1, -1, -1, 0, 0, 1, 1, 1};
10 int dn[8] = {-1, 0, 1, -1, 1, -1, 0, 1};
11 
12 bool altas[maxm][maxn];
13 int target; // 目标状态压缩
14 int ans;
15 
16 void expand() {
17     for (int i = 1; i <= n; ++i) {
18         altas[0][i] = altas[m][i];
19         altas[m + 1][i] = altas[1][i];
20     }
21     for (int i = 1; i <= m; ++i) {
22         altas[i][0] = altas[i][n];
23         altas[i][n + 1] = altas[i][1];
24     }
25     altas[0][0] = altas[m][n];
26     altas[0][n + 1] = altas[m][1];
27     altas[m + 1][0] = altas[1][n];
28     altas[m + 1][n + 1] = altas[1][1];
29 }
30 
31 int neighborCount(int i, int j) {
32     int count = 0;
33     for (int k = 0; k < 8; ++k) {
34         int next_i = i + dm[k];
35         int next_j = j + dn[k];
36         if (altas[next_i][next_j])
37             ++count;
38     }
39     return count;
40 }
41 
42 bool hasLife(int i, int j) {
43     int neighbors = neighborCount(i, j);
44     bool hasCell = false;
45     if (altas[i][j] && 2 <= neighbors && neighbors <= 3) {  // 如果原先有生命,并且邻居的数量是2-3,则存活
46         hasCell = true;
47     } else if (!altas[i][j] && neighbors == 3){
48         hasCell = true;
49     }
50     return hasCell;
51 }
52 
53 void dfs(int cur) {
54     if (cur == m * n) {
55         expand();
56         int status = 0;
57         for (int i = 1; i <= m; ++i) {
58             for (int j = 1; j <= n; ++j) {
59                 if (hasLife(i, j)) {
60                     status += 1 << ((i - 1)*n + (j - 1));
61                 }
62             }
63         }
64         if (status == target)
65             ++ans;
66         return;
67     }
68     int cur_m = cur / n;
69     int cur_n = cur % n;
70     altas[cur_m + 1][cur_n + 1] = true;
71     dfs(cur + 1);
72     altas[cur_m + 1][cur_n + 1] = false;
73     dfs(cur + 1);
74 }
75 
76 int main() {
77     int cases = 0;
78     while (++cases, scanf("%d%d", &m, &n), m != 0 && n != 0) {
79         int t; scanf("%d", &t); target = 0; ans = 0;
80         int ta, tb;
81         while (t--) {
82             scanf("%d%d", &ta, &tb);
83             target += 1 << (ta*n + tb);
84         }
85         dfs(0);
86         cout << "Case " << cases << ": ";
87         ans == 0 ? (cout << "Garden of Eden." << endl) : (cout << ans << " possible ancestors." << endl);
88     }
89     return 0;
90 }

 

posted @ 2016-01-08 14:25  MchCyLh  阅读(244)  评论(0编辑  收藏  举报