Codeforces Gym 100650C The Game of Efil 模拟+阅读题
原题链接:http://codeforces.com/gym/100650/attachments/download/3269/20052006-acmicpc-east-central-north-america-regional-contest-ecna-2005-en.pdf
题意
玩过这个游戏的人会比较熟悉,题目指出,每个细胞如果四周细胞太少了,就会孤独而死,如果细胞周围细胞太多了,就会挤死。给你个布局,问你他的上一代布局会有几种。不过这道题的关键在于wrap around这个词,即边界是循环的。
题解
做法是直接暴力枚举上一个的状态,然后检查。
代码
#include<queue> #include<vector> #include<iostream> #include<cstring> #include<cstdio> #define MAX_N 16 using namespace std; int n,m; bool G[MAX_N][MAX_N]; int k; int dx[8]={1,0,-1,0,1,1,-1,-1},dy[8]={0,1,0,-1,-1,1,1,-1}; bool v[MAX_N][MAX_N]; void generate() { bool tmp[MAX_N][MAX_N]; memset(tmp,0,sizeof(tmp)); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { int cnt = 0; for (int k = 0; k < 8; k++) { int nx = dx[k] + i, ny = dy[k] + j; nx = (nx + n) % n, ny = (ny + m) % m; if (v[nx][ny])cnt++; } if (v[i][j]) { if (cnt <= 1 || cnt >= 4) tmp[i][j] = 0; else tmp[i][j] = 1; } else if (cnt == 3)tmp[i][j] = 1; } for (int i = 0; i < n; i++) for (int j = 0; j< m; j++)v[i][j] = tmp[i][j]; } bool check(){ for(int i=0;i<n;i++) for(int j=0;j<m;j++)if(G[i][j]!=v[i][j])return false; return true; } int main() { int cas = 0; while (true) { int ans = 0; scanf("%d%d", &n, &m); if (n == 0 && m == 0)break; memset(G, 0, sizeof(G)); scanf("%d", &k); for (int i = 0; i < k; i++) { int u, v; scanf("%d%d", &u, &v); G[u][v] = 1; } for (int s = 0; s < (1 << (n * m)); s++) { int t = s; memset(v, 0, sizeof(v)); for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) { if (t & 1)v[i][j] = 1; else v[i][j]=0; t >>= 1; } generate(); if (check())ans++; } if (ans) printf("Case %d: %d possible ancestors.\n", ++cas, ans); else printf("Case %d: Garden of Eden.\n", ++cas); } return 0; }