蓝桥杯:生命游戏

这篇博客介绍了康威生命游戏中的一种特殊模式——Gosper glider gun,讨论了如何计算在第1000000000代时活着的细胞数量。博客提到解决问题的关键在于处理细胞状态的迭代,注意细节如矩形区域的扩大,并提供了最终结果:166666713个活着的细胞。

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


标题:生命游戏

康威生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。  
这个游戏在一个无限大的2D网格上进行。

初始时,每个小方格中居住着一个活着或死了的细胞。
下一时刻每个细胞的状态都由它周围八个格子的细胞状态决定。

具体来说:

1. 当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时, 该细胞变成死亡状态。(模拟生命数量稀少)
2. 当前细胞为存活状态时,当周围有2个或3个存活细胞时, 该细胞保持原样。
3. 当前细胞为存活状态时,当周围有3个以上的存活细胞时,该细胞变成死亡状态。(模拟生命数量过多)
4. 当前细胞为死亡状态时,当周围有3个存活细胞时,该细胞变成存活状态。 (模拟繁殖)

当前代所有细胞同时被以上规则处理后, 可以得到下一代细胞图。按规则继续处理这一代的细胞图,可以得到再下一代的细胞图,周而复始。

例如假设初始是:(X代表活细胞,.代表死细胞)
.....
.....
.XXX.
.....

下一代会变为:
.....
..X..
..X..
..X..
.....

康威生命游戏中会出现一些有趣的模式。例如稳定不变的模式:

....
.XX.
.XX.
....

还有会循环的模式:

......      ......       ......
.XX...      .XX...       .XX...
.XX...      .X....       .XX...
...XX.   -> ....X.  ->   ...XX.
...XX.      ...XX.       ...XX.
......      ......       ......


本题中我们要讨论的是一个非常特殊的模式,被称作"Gosper glider gun":

......................................
.........................X............
.......................X.X............
.............XX......XX............XX.
............X...X....XX............XX.
.XX........X.....X...XX...............
.XX........X...X.XX....X.X............
...........X.....X.......X............
............X...X.....................
.............XX.......................
......................................

假设以上初始状态是第0代,请问第1000000000(十亿)代一共有多少活着的细胞?

注意:我们假定细胞机在无限的2D网格上推演,并非只有题目中画出的那点空间。
当然,对于遥远的位置,其初始状态一概为死细胞。

注意:需要提交的是一个整数,不要填写多余内容。

思路:这道题其实很简单,一个一个处理即可,但需注意的细节很多,比如在每一代扩展的时候,其相应的矩形区域都会扩大,所以不能把矩形区域设置的太小,利用excel处理数据进行分析得出结论。

定义变量时最好初始化,不然真的错的离谱,只因没初始化0

//对矩阵的处理
#include<bits/stdc++.h>
using namespace std;
struct node{
	int vis=0;
	//int c[11][38];
	int c[411][438];
}nd[110];
int move_x[8]={-1,-1,-1,0,0,1,1,1};
int move_y[8]={-1,0,1,-1,1,-1,0,1};
int main(){
	freopen("1.txt","r",stdin);
	freopen("2.txt","w",stdout);
	string s;
	nd[0].vis=0;
	int cnt2=0;
	int v[11][38];
	for(int i=0;i<11;i++){
		cin>>s;
		for(int j=0;j<s.size();j++){
			if(s[j]=='.'){
				v[i][j]=0;
			}else{
				v[i][j]=1;
				cnt2++;
			}
		}
	}
	//cout<<"0="<<cnt2<<endl;
	cout<<cnt2<<endl;
	for(int i=0;i<411;i++){
		for(int j=0;j<438;j++){
			if(i>=200&&i<211&&j>=200&&j<238){
				nd[0].c[i][j]=v[i-200][j-200];
			}else{
				nd[0].c[i][j]=0;
			}
		}
	}
	int flag=0;
	for(int k=1;k<=100;k++){
		for(int i=0;i<411;i++){
			for(int j=0;j<438;j++){
				int sum1=0;//周围的活细胞 
				//int sum2=0;//周围的死细胞 
			   for(int ii=0;ii<8;ii++){
			   	  int xx=i+move_x[ii];
				  int yy=j+move_y[ii];
			   	  if(xx>=0&&xx<=410&&yy>=0&&yy<=437){
			   	  	if(nd[k-1].c[xx][yy]==1){
			   	  		sum1++;
						 }
						 //else{sum1++;}
					 }
		       }
			   if(nd[k-1].c[i][j]==1){
			   	if(sum1<2||sum1>3){
			   		nd[k].c[i][j]=0;
				   }else if(sum1==2||sum1==3){
				   	nd[k].c[i][j]=1;
				   }
			   }else{
			   	if(sum1==3){
			   		nd[k].c[i][j]=1;
				   }else{
				   	nd[k].c[i][j]=0;
				   }
			   }	
			}
		}
		//cout<<"k="<<k<<endl;
		int cnt=0;
		for(int i=0;i<411;i++){
			for(int j=0;j<438;j++){
				if(nd[k].c[i][j]){cnt++;}
				//cout<<" "<<nd[k].c[i][j];
			}
			//cout<<endl;
		}
		//cout<<k<<"="<<cnt<<endl;
		cout<<cnt<<endl;
	}
	return 0;
}

对数据的处理

 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll x=1e9;
int main(){
	cout<<"lll"<<" "<<x/30<<endl; 
	ll sum=0;
	sum+=(x/30)*5;
	x=x%30;
	cout<<"x="<<x<<endl;
	int s[30]={3,4,5,3,-7,7,-3,13,-19,6,2,4,1,1,-14,2,3,6,1,0,0,-5,11,-17,7,-3,0,3,-2,-7};
	int cnt=0;
	for(int i=0;i<x;i++){
	   cnt+=s[i];
	}
	cout<<cnt<<" "<<"jjj"<<endl;
	sum+=cnt;
	sum+=36;//初始细胞数 
	cout<<sum<<endl;
	return 0;
} 

最后的结果为: 166666713

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值