解题技巧:
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 }