题目内容:
这是细胞自动机的非图形版本。细胞自动机是指在一个二维网格内,每一个网格是一个细胞。每个细胞有活和死两种状态。
初始时刻,有些细胞是活的,有些细胞是死的。自动机的每一步,根据每个细胞周围8个格子内的其他细胞的生存情况决定这个细胞下一步是否存活。具体的规则如下:
-
如果该细胞现在是活的,并且周围8个格子中有2或3个活着的细胞,则继续存活;如果周围8个格子中的活着的细胞数量少于2个或多于3个,则死亡;
-
如果该细胞现在是死的,并且周围8个格子中正好有3个活着的细胞,则细胞复活。
-
位于整个网格边缘和顶角的细胞,它的周围细胞可能少于8个。即越过网格的边界不再有细胞。
-
每个细胞的生死变化,都不会影响当前这一步周围的细胞,只会在下一步表现出来。
提示:课程中的代码与上一句描述不同。
输入格式:
首先输入两个正整数,范围为[3,102],依次表示网格的宽度和高度。
然后输入多组正整数,依次表示一个活着的细胞的网格位置,每组数字中,第一个表示行号,第二个表示列号,均从0开始编号。
最后,以“-1 -1”表示不再有活着的细胞。-1 -1不是有效的位置。
然后,以一个正整数,范围为[1,10000],表示要求细胞自动机执行的步数。
输出格式:
输出一个正整数,表示执行完毕后,剩下的活着的细胞的数量。
输入样例:
3 3
1 1 1 2 0 1 2 1
-1 -1
1
输出样例:
7
时间限制:500ms内存限制:32000kb
我的错误代码:【想象很丰满,现实很骨感啊!为啥我老是越写越复杂TT,等会儿再来改吧】
package cells;
import java.util.Scanner;
public class Cell {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//创建二维数组
int weight = in.nextInt();
int height = in.nextInt();
boolean[][] cell = new boolean[weight][height];
//将存活的细胞存入二维数组中
int i = in.nextInt();
int j = in.nextInt();
while((i!=-1)&&(j!=-1)) {//若不是[-1][-1]则判断该处细胞存活
cell[i][j] = true;
i = in.nextInt();//再次输入存活细胞位置,直到[-1][-1]
j = in.nextInt();
}
//输入要走的步数
int steps = in.nextInt();
int step=0;//计数器
//细胞位置判断
boolean angle = (cell[0][0] || cell[0][height-1] || cell[weight-1][0] || cell[weight-1][height-1]);//网格角落
//对数组进行遍历,从数组的[0][0]开始依次盘查细胞,假设边缘细胞在网格之外没有存活的细胞
while(step==steps) {
for(int x =0; x<weight-1; x++) {//从数组第一位开始盘查细胞
for(int y=0;y<height-1;y++) {
if(angle) {//若是在网格的四个角,那么是否存活都要判断它周围的三个细胞
if(cell[0][0]==false) {
if((cell[1][0]=false)&&(cell[1][1]=false)&&(cell[0][1]=false)) {
cell[0][0]=false;
}
}else{
if((cell[1][0]=false)&&(cell[1][1]=false)&&(cell[0][1]=false)||(cell[1][0]=false)&&(cell[1][1]=false)&&(cell[0][1]=false))
}
if(cell[0][height-1]==false) {
if((cell[0][height-2]&&cell[1][height-2]&&cell[1][height-1])==false)
{cell[0][height-1]=false;}else {cell[0][height-1]=true;}
}
if(cell[weight-1][0]==false) {
if((cell[weight-2][0]&&cell[weight-2][1]&&cell[weight-1][1])==false)
{cell[weight-1][0]=false;}else {cell[weight-1][0]=true;}
}
if(cell[weight-1][height-1]==false) {
if((cell[weight-2][height-1]&&cell[weight-2][height-2]&&cell[weight-1][height-2])==false)
{cell[weight-1][height-1]=false;}else {cell[weight-1][height-1]=true;}
}
}
}
}
}
step++;//完成一轮后计数器加一
}
}
}
改完后的代码:【我都服了,一直都是索引越界,怎么改都不行,kao】
import java.util.Scanner;
public class Cell {
int weight;//宽
int height;//高
int[][] oldCell;//旧网格
int[][] newCell;//新网格
Scanner in = new Scanner(System.in);
int steps = in.nextInt();//需要走的步数
void OldAndWeight() {//定义两个二维数组
weight = in.nextInt();
height = in.nextInt();
oldCell = new int[weight+2][height+2];//旧的网格
newCell = new int[weight+2][height+2];//新的网格
for(int p=0;p<weight+2;p++) {//初始化
for(int q=0;q<height+2;q++) {
oldCell[p][q]=0;
newCell[p][q]=0;
}
}
//将存活的细胞存入二维数组中
int i = in.nextInt();
int j = in.nextInt();
while((i!=-1)&&(j!=-1)) {//若不是[-1][-1]则判断该处细胞存活
oldCell[i+1][j+1] = 1;
newCell[i+1][j+1] = 1;
i = in.nextInt();//再次输入存活细胞位置,直到[-1][-1]
j = in.nextInt();
}
}
void Step() {//每一步遍历二维数组
int step=0;//计步器
int x =0;
int y =0;
int count = getNeighbor(x,y);
//对数组进行遍历,从数组的[0][0]开始依次盘查细胞,假设边缘细胞在网格之外没有存活的细胞
while(step<=steps) {
for(x =1; x<weight+1; x++) {//从数组第一位开始盘查细胞
for(y=1;y<height+1;y++) {
if(oldCell[x][y]==1) {//如果该位置是活细胞
if((count==2)||(count==3)) {
oldCell[x][y]=1;
newCell[x][y]=1;
}else {
oldCell[x][y]=0;
newCell[x][y]=0;
}
}else {//如果细胞不存活
if(count==3) {
oldCell[x][y]=1;
newCell[x][y]=1;
}else {
oldCell[x][y]=0;
newCell[x][y]=0;
}
}
}
}
}
step+=1;//完成一轮后计数器加一
}
int getNeighbor(int i,int j){//计算位置为i,j的细胞周围活的细胞的数量
int temp=0;
temp+=oldCell[i-1][j]+oldCell[i+1][j]+oldCell[i][j-1]+oldCell[i][j+1];
temp+=oldCell[i-1][j-1]+oldCell[i-1][j+1]+oldCell[i+1][j-1]+oldCell[i+1][j+1];
return temp;
}
int Number() {//计算新的网格中存活的细胞
int newNumber = 0;
for(int i =1; i<weight+1; i++) {//从数组第一位开始盘查细胞
for(int j=1;j<height+1;j++) {
if(newCell[i][j]==1) {
newNumber++;
}else {
newNumber+=0;
}
}
}
return newNumber;
}
void test() {
OldAndWeight();
Step();
System.out.println(Number());
}
public static void main(String[] args) {
new Cell().test();
}
}