蓝桥杯------2017 Java B组 国赛:第二题 生命游戏_由john conway发明的生命游戏中,细胞存在两种状态-程序员宅基地

技术标签: Java  蓝桥杯  

题目描述:

康威生命游戏是英国数学家约翰·何顿·康威在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网格上推演,并非只有题目中画出的那点空间。
当然,对于遥远的位置,其初始状态一概为死细胞。

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

     首先总结认真审题,总结题目的信息,知道细胞分死亡存活两种状态,对于死亡的细胞只要周围(八个方向)存活细胞数等于3,则该细胞能恢复活性;而对于存活的细胞,周围存活细胞数小于2或者大于3则会死亡,周围存活细胞数等于2或者3才能存活

思路:

    鉴于这只是一道填空题,所以就不去考虑什么骚操作了,首先把"Gosper glider gun"存入记事本中,再读取来处理,用一个二维整形数组存储这个表,存活细胞记为 1死亡细胞则记为 0

    然后再用一个LinkedList来存存活的细胞坐标位置,这样方便每一代更替时进行处理,毕竟只有当周围有存活细胞时,死亡细胞才有可能复活,然后就是不断循环重复对每个存活的细胞及其周边八个方向的死亡细胞进行判断,判断死亡细胞是否会复活,存活细胞是否会死亡。

    得到其每一代的存活细胞数量,观察其细胞增长是否有规律。

 

代码如下:

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.LinkedList;	

public class Main {
	public static final int MAX_NUMBER = 1000;
	
	public static int[][] map = new int[MAX_NUMBER][MAX_NUMBER];
	public static int[][] tmpMap;
	public static int[][] beenCheck;
	
	public static LinkedList<coor> life = new LinkedList<coor>();
	
	public static final int[][] dir = new int[][] {
   {-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
	
	//自定义的坐标类
	public static class coor {
		public int x;
		public int y;
		coor(int x, int y) {
			this.x = x;
			this.y = y;
		}
	}
	
	//判断当前存活细胞的去留
	public static void Judge(coor c) {
		
		int countLife = 0;
		
		for(int i = 0; i < dir.length; i++) {
			//周围的存活细胞
			if(map[c.x + dir[i][0]][c.y + dir[i][1]] == 1) {
				countLife++;
			}
			//周围的死亡细胞
			else {
				//尚未被检查过
				if(beenCheck[c.x + dir[i][0]][c.y + dir[i][1]] == 0) {
					int countDead = 0;
					int tmpR = c.x + dir[i][0];
					int tmpC = c.y + dir[i][1];
					//遍历该死亡细胞的八个方向
					for(int j = 0; j < dir.length; j++) {
						if(map[tmpR + dir[j][0]][tmpC + dir[j][1]] == 1) {
							countDead++;
						}
					}
					
					//周围细胞数为3,死亡细胞翻身
					if(countDead == 3) {
						tmpMap[tmpR][tmpC] = 1;
						life.addLast(new coor(tmpR, tmpC));
					}
					//该点被检查标志
					beenCheck[tmpR][tmpC] = 1;
				}
			}
		}
		
		//对当前细胞的生死去留判断
		if(countLife == 3 || countLife == 2) {
			life.addLast(c);
			tmpMap[c.x][c.y] = 1;
		}
	}
	
	
	public static void main(String[] args) throws IOException {
		File file = new File("C:\\Users\\vMars\\Desktop\\input\\in.txt");
		BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
		String str = null;
		int row = 0;
		while((str = br.readLine()) != null) {
			System.out.println(str);
			//不要离边边太近,防止溢出
			int step = 10;
			for(int column = 0; column < str.length(); column++) {
				if(str.charAt(column) == 'X') {
					map[step + row][step + column] = 1;
					life.addLast(new coor(step+row, step+column));
				}
				else {
					map[step + row][step + column] = 0;
				}
			}
			row++;
		}
		
		//演变50代
		for(int i = 0; i <= 50; i++) {
			System.out.println(life.size());
			beenCheck= new int[MAX_NUMBER][MAX_NUMBER];
			tmpMap = new int[MAX_NUMBER][MAX_NUMBER];
			//记录当前的存活细胞个数
			int lifeSize = life.size();
			for(int j = 0; j < lifeSize; j++) {
				//这样就可以只判断当前存活的,而不影响后面经过判断得到新的存活细胞坐标(因为是尾插)
				Judge(life.getFirst());
				life.removeFirst();
			}
			map = tmpMap;
		}
				
		
		br.close();
	}
}

    从上面代码可以得到该图形50代的繁殖数量变化情况,将其存到Excel表中观察分析。

    可以发现该图的细胞繁殖数量每30代一次循环,且每30代净增长为5个存活细胞,所以可以通过计算器算:

1000000000  / 30 = 33333333.33333333

1000000000  % 30 = 10 ,通过表格计算可得,经过10代净增长为 12

所以结果等于:33333333*5 + 36(第0代)+12 = 166666713

 

 

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/vMars_K/article/details/90380807

智能推荐

Vue中剪贴板库v-clipboard工具使用案例_JackieDYH的博客-程序员宅基地

文章浏览阅读1.7k次,点赞3次,收藏5次。v-clipboard剪贴板库安装npm install --save v-clipboardmain.js引入import Vue from 'vue'import Clipboard from 'v-clipboard'Vue.use(Clipboard)模板中调用<template> <div> <button type="dashed" v-clipboard:copy="code" v-clipboard:su_v-clipboard

boost:regex分割字符串(带有'\'字符)_regex 根据特殊字符分割-程序员宅基地

文章浏览阅读3.1k次。在实际的应用中,经常用到boost:regex进行字符串的分割,特别是windows下的路径字符串的分割,由于windows的路径字符串带有特殊字符'\',boost:regex需要对此进行特殊处理,下面举例说明,分割字符串的正则表达式如下:boost::regex re_regex 根据特殊字符分割

OC数组和字典小项目_省市区-程序员宅基地

文章浏览阅读549次。本篇博客主要内容是用数组和字典嵌套使用保存从文件中读取出来的省市区的名字,我的代码中有很多注释很适合新手学习.具体内容是用一个省的数组保存所有的省的字典,而省的字典包含省的名字和城市数组,城市数组包含所有城市字典,城市字典包含城市的名字和区数组,区数组包含的是所有区的名字

卸载mysql的时候报错缺少dll文件_PHP_解决phpmyadmin中缺少mysqli扩展问题的方法,phpMyAdmin错误 缺少 mysqli 扩展。 - phpStudy...-程序员宅基地

文章浏览阅读221次。解决phpmyadmin中缺少mysqli扩展问题的方法phpMyAdmin错误 缺少 mysqli 扩展。请检查 PHP 配置 的解决方案phpMyAdmin 缺少 mysqli 扩展。请检查 PHP 配置 的解决方案:缺少 mysqli 扩展。请检查 PHP 配置。打开你的php.ini->一般在C:WINDOWS目录下。找到;extension=php_msql.dll;extensi...

Zigbee避开Wifi的信道,提升通讯质量_zigbee通道号哪个最稳定-程序员宅基地

文章浏览阅读1k次,点赞2次,收藏4次。ZigBee 提供 16 个物理信道,必须在同一通道下的节点才可能互相通信。在同一工作区域内的相邻网络,建议使用不同的通道,以免相互干扰导致通信效率降低。比如,工作区域内存在大量的 2.4G Wi-Fi 热点,可能会降低 ZigBee 的通信效率,这时可选择 CH11、15、20、25、26,达到有效避开干扰的目的。具体分析参考前辈帖子:对于Zigbee和Wifi的信道重叠,百度有不少热心..._zigbee通道号哪个最稳定

关于IOS 5-程序员宅基地

文章浏览阅读60次。IOS 5比IOS 4增加了很多特性,简单的列举下1.新增了icloud,云同步服务。2.新增了twitter。3.将视频与音乐进行了分离。4.推送通知系统。5 .新增了无线同步功能。在我们开发当中,有StoryboardStoryboard(故事板)是XCode4和iOS5提供的一个用于控制View Controller之间跳转关系...

随便推点

反向ajax实现-程序员宅基地

文章浏览阅读7.8k次。英文原文:Reverse Ajax, Part 1: Introduction to Comet在过去的几年中,web开发已经发生了很大的变化。现如今,我们期望的是能够通过web快速、动态地访问应用。在这一新的文章系列中,我们学习如何使用反向Ajax(Reverse Ajax)技术来开发事件驱动的web应用,以此来实现更好的用户体验。客户端的例子使用的是JQuery JavaScrip

【社团检测】社团检测之标签传播算法Python实现_copra社团-程序员宅基地

文章浏览阅读2.6k次。转载自:http://blog.csdn.net/DreamHome_S/article/details/78662197主要优点:时间复杂度近似线性,不需要事先知道社区数量。主要算法流程:首先为每个节点设置唯一标签,接着迭代依次更新各个节点,针对每个节点,通过统计节点邻居的标签,选择标签数最多的标签更新该节点,如果最多便签数大于一,则从中随机选择一个标签更新该节点,直到收敛为止。标签传播算法的节_copra社团

TODO —— mmdetection_目标检测todo-程序员宅基地

文章浏览阅读708次。导言mmdetection:商汤科技和香港中文大学开源了一个基于Pytorch实现的深度学习目标检测工具箱mmdetection,支持Faster-RCNN,Mask-RCNN,Fast-RCNN等主流的目标检测框架,后续会加入Cascade-RCNN以及其他一系列目标检测框架相比于Facebook开源的Detectron框架,作者声称mmdetection有三点优势:performance稍高、训练速度稍快、所需显存稍小代码学习链接:Github包括有:Multiple Base Networ_目标检测todo

django 创建完成后没有templates文件夹解决办法-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏18次。我通过django-admin startproject mysite 和 在mysite文件夹中执行python manage.py startapp app001 创建一个APP名字文件夹中没有装html的文件夹templates只需要先在mysite文件夹下创建一个名为templates的文件夹然后在setting.py中配置路径添加红框中的内容就可以了在templat..._django没有templates

double和Double的区别-程序员宅基地

文章浏览阅读5.9k次,点赞4次,收藏17次。一、区别1. double是基本数据类型,Double是原始数据类型5. double没有方法,Double有自己的属性和方法3. double只创建引用,Double创建对象4. 集合类不能存放double,只能存放Double5. double存放在栈中,Double存放在堆中 栈的存取速度要高于堆,另外栈中的数据可以共享double不会创建对象,只会建立两个引用,同时指向变量“0”(栈数据共享)doublea=0;doubleb=0;..._double和double的区别

Linux -- cp-程序员宅基地

文章浏览阅读71次。CP(1) User Commands CP(1)NAME cp - copy files and directoriesSYNOPS...

推荐文章

热门文章

相关标签