最大的细胞数量(模拟+搜索)

本文介绍了一个基于规则的细胞演化模拟程序,通过模拟不同世代细胞的存活和死亡,寻找21个世代内细胞数量的最大值和最小值。使用C++实现,涉及数组遍历和条件判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

一个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;
 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值