2017年第八届蓝桥杯 JavaB组国赛 第二题 生命游戏


标题:生命游戏

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

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

 

思路是:把图存进数组(边缘要扩充一些死细胞,越多越好!) 接下来用旧数组遍历每个格子,求取该格子下一代的细胞状态,寻找规律,最后发现后一代活细胞数和前一代活细胞的数是一串循环,即是循环,可以将循环存入数组,需要求循环的数值和 和 一亿除(模)循环数字的大小。

 

package code.tu;

import java.util.Scanner;

/**
 * @author young
 * @ClassName: 生命游戏
 * @Description: TODO()
 * @date 2019/4/2 12:32
 */


public class 生命游戏 {

    /**
     * ......................................
     * ......................................
     * .........................X............
     * .......................X.X............
     * .............XX......XX...............
     * ............X...X....XX...............
     * ...........X.....X...XX...............
     * ...........X...X.XX....X.X............
     * ...........X.....X.......X............
     * ............X...X.....................
     * .............XX.......................
     * ......................................
     * ......................................
     */

    public static void main(String[] args) {

        String s ="......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                ".................................X....................\n" +
                "...............................X.X....................\n" +
                ".....................XX......XX............XX.........\n" +
                "....................X...X....XX............XX.........\n" +
                ".........XX........X.....X...XX.......................\n" +
                ".........XX........X...X.XX....X.X....................\n" +
                "...................X.....X.......X....................\n" +
                "....................X...X.............................\n" +
                ".....................XX...............................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................\n" +
                "......................................................";
        String[] lines = s.split("\n");
        char [][] data = new char[lines.length][];



        for(int i = 0;i<lines.length;i++){
            data[i] = lines[i].toCharArray();
        }

        int num = sum(data);
        int first = num;
        int cha;

        for (int i = 0;i<60;i++){
            data = fun(data);
            int num1 = sum(data);
            cha = num1 - num;
            System.out.print(cha+" ");
            num = num1;
//            printer(data);
        }

//        循环打印
        String [] f = "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".split(" ");


        int A = 1000000000/30;
        int B = 1000000000%30;

        int value1 = 0;
        for (String item : f){
            value1+= Integer.parseInt(item);
        }
        System.out.println(" = "+value1);

        int value2 = 0;
        for(int i = 0;i<B;i++){
            value2 += Integer.parseInt(f[i]);
        }


        System.out.println(first + A*value1+value2);



    }

    private static void printer(char[][] data) {
        for (char[] dataItem : data){
            System.out.println(String.valueOf(dataItem));;
        }
    }

    private static int sum(char[][] data) {
        int tot = 0;
        for (int i = 0;i<data.length;i++){
            for (int j = 0;j<data[0].length;j++){
                if (data[i][j] == 'X'){
                    tot ++;
                }
            }
        }
        return tot;
    }

    private static char[][] fun(char[][] data) {

        char[][] newData = new char[data.length][];

        for (int i = 0;i<newData.length;i++){
            newData[i] = "......................................................".toCharArray();
        }

        for (int y = 1;y<data.length-1;y++){
            for (int x = 1;x<data[0].length-1;x++){

                int env = search(data,y,x);

                if (data[y][x] == '.'){
                    if (env == 3){
                        newData[y][x] = 'X';
                    }
                }else {
                    if (env == 2 ||  env == 3){
                        newData[y][x] = 'X';
                    }
                }
            }
        }

        return newData;


    }




    private static int search(char[][] data, int y, int x) {

        int tot = 0;

        if (data[y-1][x-1] == 'X'){
            tot++;
        }

        if (data[y-1][x] == 'X'){
            tot++;
        }
        if (data[y-1][x+1] == 'X'){
            tot++;
        }
        if (data[y][x-1] == 'X'){
            tot++;
        }
        if (data[y][x+1] == 'X'){
            tot++;
        }
        if (data[y+1][x-1] == 'X'){
            tot++;
        }
        if (data[y+1][x+1] == 'X'){
            tot++;
        }
        if (data[y+1][x] == 'X'){
            tot++;
        }
        return tot;
    }


}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值