• 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网格上推演,并非只有题目中画出的那点空间。
    当然,对于遥远的位置,其初始状态一概为死细胞。
    
    注意:需要提交的是一个整数,不要填写多余内容。
    
    
    package 生命游戏;
    

    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Map;
    import java.util.Scanner;

    public class Main {
    //文件终止符问题, 点出去再点进来,无语。。。。。
    static int[][] dir = {{1,-1},{1,1},{-1,1},{-1,-1},{0,1},{0,-1},{1,0},{-1,0}};
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    Map<Integer, HashSet> lifemap = new HashMap<>();//记录本轮生命体
    Map<Integer, HashSet> nmap = new HashMap<>();//记录下一轮生命体
    Map<Integer, HashSet> visit = new HashMap<>();//在每一轮中记录是否被访问过
    //初始化
    int row = 0;//y的值
    String str;
    //处理输入
    while(sc.hasNext()) {
    str = sc.nextLine();
    for(int x = 0; x < str.length(); x++) {
    if(str.charAt(x) == ‘X’) {
    if(lifemap.containsKey(x)) {//把这个点加到map里
    lifemap.get(x).add(row);
    }else {
    HashSet nset = new HashSet<>();
    nset.add(row);
    lifemap.put(x, nset);
    }
    }
    }
    row++;
    }
    int fans = 0;
    for(Integer x : lifemap.keySet()) {
    for(Integer y : lifemap.get(x)) {
    //System.out.println(x + " " + y);
    fans++;
    }
    }
    System.out.println(fans);
    //模拟游戏
    int cnt = 0;
    while(cnt < 100) {
    for(Integer x : lifemap.keySet()) {//第一轮
    for(Integer y : lifemap.get(x)) {

                    if(visit.containsKey(x)) //在某个点周围被先访问了,直接跳过
                        if(visit.get(x).contains(y))
                            continue;
                    
                    if(visit.containsKey(x)) {//把这个点标记已访问
                        visit.get(x).add(y);
                    }else {
                        HashSet<Integer> nset = new HashSet<>();
                        nset.add(y);
                        visit.put(x, nset);
                    }
                    
                    int num = 0;
                    //System.out.print(x + " " + y + " : ");
                    for(int[] d : dir) {//周围八个点,第一层
                        int curx = x + d[0];
                        int cury = y + d[1];
                        boolean alive = false;
                        if(lifemap.containsKey(curx)) 
                            if(lifemap.get(curx).contains(cury)) {
                                num++;
                                alive = true;
                            }
                        if(alive)
                            continue;
                        //System.out.print(curx + " " + cury + " : ");
                        if(visit.containsKey(curx)) //如果被访问过,就跳过这个点
                            if(visit.get(curx).contains(cury))
                                continue;
                        
                        if(visit.containsKey(curx)) {//把这个点标记已访问
                            visit.get(curx).add(cury);
                        }else {
                            HashSet<Integer> nset = new HashSet<>();
                            nset.add(cury);
                            visit.put(curx, nset);
                        }
                        
                        int cnum = 0;
                        for(int[] cd : dir) {//周围8个点,第二层
                            int cx = curx + cd[0];
                            int cy = cury + cd[1];
                            if(lifemap.containsKey(cx)) 
                                if(lifemap.get(cx).contains(cy)) {
                                    cnum++;
                                }
                        }
                        //System.out.print(cnum);
                        //System.out.println();
                        if(cnum == 3) {
                            if(nmap.containsKey(curx)) {//把这个点加到map里
                                nmap.get(curx).add(cury);
                            }else {
                                HashSet<Integer> nset = new HashSet<>();
                                nset.add(cury);
                                nmap.put(curx, nset);
                            }
                        }
                    }
                    
                    //System.out.print(num);
                    //System.out.println();
                    if(num < 2) {
                        ;
                    }else if(num >=2 && num <= 3) {
                        if(nmap.containsKey(x)) {
                            nmap.get(x).add(y);
                        }else {
                            HashSet<Integer> nset = new HashSet<>();
                            nset.add(y);
                            nmap.put(x, nset);
                        }
                    }else{
                        ;
                    }
                    
                }
            }
            lifemap = new HashMap<>();
            lifemap.putAll(nmap);
            nmap.clear();
            visit.clear();
            cnt++;
            int ans = 0;
            for(Integer x : lifemap.keySet()) {
                for(Integer y : lifemap.get(x)) {
                    //System.out.println(x + " " + y);
                    ans++;
                }
            }
            System.out.println(ans);
        }
        sc.close();
    }
    

    }

  • 相关阅读:
    Sql2008 全文索引 简明教程
    sql server 全文检索 使用
    数据库分词查询的优缺点以及英文和中文各自的分词方法(一)
    win10中打开SQL Server配置管理器方法
    Asp.net 中高亮显示搜索关键字简单方法
    EntityFramework优缺点
    LoadXml载入Xhtml文件速度很慢
    c#无限循环线程如何正确退出
    线程的等待方法:join
    C#如何优雅的结束一个线程
  • 原文地址:https://www.cnblogs.com/a1439775520/p/13077263.html
Copyright © 2020-2023  润新知