期末考试编程题:细胞自动机(30分)

这是一个关于细胞自动机的编程题目,要求在二维网格中根据特定规则模拟细胞的生死状态。程序需要处理输入的网格尺寸、初始活细胞位置及执行步数,输出最后存活的细胞数量。提供的代码存在错误,需要进行修正。

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

题目内容:

这是细胞自动机的非图形版本。细胞自动机是指在一个二维网格内,每一个网格是一个细胞。每个细胞有活和死两种状态。

初始时刻,有些细胞是活的,有些细胞是死的。自动机的每一步,根据每个细胞周围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();
    }
}  
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值