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.
", ++cas, ans);
        else
            printf("Case %d: Garden of Eden.
", ++cas);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/HarryGuo2012/p/4740511.html