您的位置:首页 > 其它

Codeforces Gym 100650C The Game of Efil 模拟+阅读题

2015-08-18 20:28 411 查看
原题链接: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: