SOJ 1171

来源:互联网 发布:东莞南城关键词优化 编辑:程序博客网 时间:2024/05/16 14:15

题意:在一块n*m的板子上,有一些细菌,如果一个细菌八个方向上细菌数为2或3,下回合保留,否则消失,如果是一个空格周围细菌数为3,则下回合长出新的,现在给出一种情况,要求出可能得到这种子代的父母有多少种情况

解法:因为这道题的规模不是很大n*m<=16,所以直接枚举所有格子的可能情况也最多就是2^16,然后根据规则算出下一个状态然后进行比较就行,不过有两个点要注意:这些格子是上下左右连通的,所以并没有越界的情况,我们只需要都加上n(m),然后取余n(m),就能将-1变成n-1(m-1),达到连通的效果,然后我是wa了一次,因为数组开太小了,因为说n*m<16,我开了6*6,然后就错了,这个很煞笔。枚举所有情况可以从0到n*m位的二进制最大数进行,然后将1维的数转成对应二维坐标,这个我也是慢慢试的,毕竟数学不好。



#include <iostream>#include <cstring>#include <cmath>using namespace std;int n,m; int target[20][20];int test[20][20];int change[20][20];int dist[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};int main(){int cas=1;while(cin >> n >> m){if(n==0&&m==0) break;memset(target,0,sizeof(target));memset(test,0,sizeof(test));int k;cin >> k;for(int i=0; i < k; ++i){int x,y;cin >> x >> y;target[x][y]=1;}/*for(int i=0; i < n; i++){for(int j=0; j < m; j++)cout << target[i][j] << " ";cout << endl;}*///查看生成的结果矩阵对不对 int res=0;int kk=pow(2,(n*m));for(int i=0; i < kk; i++){int tmp=n*m;int tmp1=i;while(tmp--){test[tmp/m][tmp%m]=tmp1%2;tmp1/=2;}//生成一种可能的父母情况 /*for(int l=0; l < n; l++){for(int j=0; j < m; j++)cout << test[l][j] << " ";cout << endl;}//cout << endl;*///查看生成的父母矩阵 for(int j=0; j < n; j++){for(int l=0; l < m; l++){int live_num=0;for(int o=0; o < 8; ++o){//上下左右是连通的,所以加n、m后取余 int tmp_x=(j+dist[o][0]+n)%n;int tmp_y=(l+dist[o][1]+m)%m;if(test[tmp_x][tmp_y])live_num++;}if(test[j][l]==1&&(live_num==2||live_num==3)) change[j][l]=1;else if(test[j][l]==0&&live_num==3) change[j][l]=1;else change[j][l]=0;}}//生成后代 /*for(int l=0; l < n; l++){for(int j=0; j < m; j++)cout << change[l][j] << " ";cout << endl;}cout << endl;*///查看产生的后代的矩阵 bool check=true;for(int j=0; j < n; j++){for(int l=0; l < m; l++){if(change[j][l]==target[j][l])continue;else {check=false;break;}}if(check==false) break;}if(check)res++;}//判断是否相同 cout << "Case " << cas << ": ";if(res==0) cout << "Garden of Eden.\n";else cout << res <<  " possible ancestors.\n" ;cas++;}}

0 0