题目:
一个N行x M列的矩形培养皿中生存着一堆细胞,在每个细胞周边的细胞存活情况决定着这个细胞本身在下个世代的存活情况。即每个细胞会且仅会被它左上、上中、右上、左边、右边、左下、下中、右下的八个细胞影响。每个世代中培养皿中各个位置的细胞存活状态规则如下:
任何活着的细胞如果在它周边存活的细胞少于两个,则死亡,因为它不受欢迎。
任何活着的细胞如果在它周边存活的细胞有两个或三个,则继续存活到下个世代。
任何活着的细胞如果在它周边存活的细胞多于三个,则死亡,因为它太受欢迎。
任何死了的细胞如果在它周边存活的细胞正好有三个,则复活,因为它是旁边细胞的结晶。
显然,这个矩形培养皿中的细胞数量在不断变化,问从第0到21个世代中,哪个世代活着的细胞数量最多,哪个世代活着的细胞数量最少?
第一行两个正整数N和M,0<N,M<50。
接下来N行,每行包含一个长度为M的字符串,代表培养皿中的细胞存活状态。初始即为第0世代。
用'#'代表存活的细胞,'.'代表死亡的细胞,输入保证每个位置有且只有存活和死亡两种状态的细胞。
输出一行四个整数A,B,C,D。
A代表最大细胞数量的世代,B代表最大细胞数量。
C代表最小细胞数量的世代,D代表最小细胞数量。
如果有多个世代都有最大细胞数量或最小细胞数量,都输出世代最小的那个。
3 3 ... ##. .#.
1 4 0 3
3 3 ... ### ...
0 3 0 3
思路:就是模拟一下细菌的存活和死亡,然后加点小搜索,还是很简单的
代码:
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
char s[51][51];
int dx[8] = {-1,-1,-1,0,1,1,1,0};
int dy[8] = {-1,0,1,1,1,0,-1,-1};
int n,m;
int b[50][50];
bool _judge(int x,int y)
{
int num = 0;
for(int i = 0;i < 8;i++)
{
int newx = x+dx[i];
int newy = y+dy[i];
if(newx >= 0&&newx < n&&newy >= 0&&newy < m&&s[newx][newy] == '#')
{
num++;
}
}
if(s[x][y] == '.'&&num == 3)
{
b[x][y] = 1;
return true;
}
else if(s[x][y] == '#')
{
if(num<2)
{
b[x][y] = 1;
return false;
}
else if(num == 2||num == 3) return true;
else if(num > 3)
{
b[x][y] = 1;
return false;
}
}
else return false;
}
int main()
{
int count = 0,k = 0;
int maxcount = 0,mincount = 0;
cin >> n >> m;
memset(s,'\0',sizeof(s));
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
cin >> s[i][j];
}
}
for(int i = 0;i < n;i++)
{
for(int j = 0;j < m;j++)
{
if(s[i][j] == '#')count++;
}
}
maxcount = mincount = count;
int maxy = 0,miny = 0;
for(int i = 1;i <= 21;i++)
{
count = 0;
memset(b,0,sizeof(b));
for(int j = 0;j < n;j++)
{
for(int k = 0;k < m;k++)
{
if(_judge(j,k))
{
count++;
}
}
}
if(count > maxcount) maxcount = count,maxy = i;
else if(count < mincount) mincount = count,miny = i;
for(int j = 0;j < n;j++)
{
for(int k = 0;k < m;k++)
{
if(b[j][k])s[j][k] = s[j][k] == '.'?'#':'.';
}
}
}
cout << maxy << " " << maxcount << " " << miny << " " << mincount;
return 0;
}