题目链接https://csustacm.fun/problem/1029
现在你参加了SXJM竞赛,你的一名队友需要你模拟一种细胞的增殖过程的影响。
假设这种细胞均为1*1的二维平面生物,他们生活在一个无限大的二维平面中该种细胞增值过程如下:
你的队友会给出一个初始的状态n*m个格子的图。在SXJM比赛中,你需要写出一个可视化程序,来模拟这个过程。 但是现在,你只需要告诉你的队友 在经过X代繁衍后,会有多少个活着的细胞。
第一行输入3个整数n,m,t(1<=n,m<=5,1<=t<=400)
之后n行,每行为一个长度为m的01字符串,1代表这个格子有一个活着的细胞
接下来有t行,表示有t次询问,每行包含一个数字Xi,询问经过Xi(Xi<=400)代繁衍后,有多少个活着的细胞
输出包含t行 每行输出一个数字表示Xi代后,有多少个活着的细胞
3 3 3
000
110
010
0
1
2
3
7
10
就是个大模拟,关键是它的平面是无限大的,它可以一直繁殖,但Xi只有400,也就是说这个矩阵最多扩充400次,那么他的大小极限也就是800*800而已,每一次向左,右,上,下扩充一次,那么我们可以将它先放在二维数组的中间以便扩充,为了减小常数,我们不能每次都从1到800跑一遍,我们从设置一个边界,每次边界向外扩充就好了,这个边界可以直接用xl,xr,yl,yr(最上面,下面,左边,右边)控制
以下是AC代码:
#include
using namespace std;
char s[10][10];
int ans[500],a[810][810][2];
int dx[]={-1,-1,-1,0,0,1,1,1},dy[]={-1,0,1,-1,1,-1,0,1};
int ok1(int x,int y,int id)
{
int sum=0;
for (int i=0; i<8; i++){
int xx=x+dx[i],yy=y+dy[i];
if (a[xx][yy][id]) sum++;
}
if (sum==2) return 1;
return 0;
}
int ok2(int x,int y,int id)
{
int sum=0;
for (int i=0; i<8; i++){
int xx=x+dx[i],yy=y+dy[i];
if (a[xx][yy][id]) sum++;
}
if (sum==0 || sum>=4) return 1;
return 0;
}
int main()
{
int n,m,t;
scanf ("%d%d%d",&n,&m,&t);
for (int i=1; i<=n; i++)
scanf ("%s",s[i]+1);
for (int i=1; i<=n; i++)
for (int j=1; j<=m; j++)
a[401+i][401+j][0]=s[i][j]-'0';
int mk=0,xl=402,xr=401+n,yl=402,yr=401+m;
for (int o=0; o<=400; o++){
for (int i=xl; i<=xr; i++)
for (int j=yl; j<=yr; j++){
if (a[i][j][mk]==1) ans[o]++;
}
for (int i=xl-1; i<=xr+1; i++)
for (int j=yl-1; j<=yr+1; j++){
if (a[i][j][mk]){
if (ok2(i,j,mk)) a[i][j][mk^1]=0;
else a[i][j][mk^1]=1;
}
else {
if (ok1(i,j,mk)) a[i][j][mk^1]=1;
else a[i][j][mk^1]=0;
}
}
xl--,xr++,yl--,yr++;
mk^=1;
}
for (int i=1; i<=t; i++){
int x;
scanf ("%d",&x);
printf ("%d\n",ans[x]);
}
return 0;
}