蓝桥杯——乳草的入侵

农民约翰一直努力让他的草地充满鲜美多汁而又健康的牧草。

可惜天不从人愿,他在植物大战人类中败下阵来。

邪恶的乳草已经在他的农场的西北部份占领了一片立足之地。

草地像往常一样,被分割成一个高度为 Y,宽度为 X 的直角网格。

(1,1) 是左下角的格(也就是说坐标排布跟一般的 X,Y 坐标相同)。

乳草一开始占领了格 (Mx,My)。

每个星期,乳草传播到已被乳草占领的格子四面八方的每一个没有很多石头的格(包括垂直与水平相邻的和对角线上相邻的格)内。

1 周之后,这些新占领的格又可以把乳草传播到更多的格里面了。

达达想要在草地被乳草完全占领之前尽可能的享用所有的牧草。

她很好奇到底乳草要多久才能占领整个草地。

如果乳草在 0 时刻处于格 (Mx,My),那么几个星期以后它们可以完全占领入侵整片草地呢

在草地地图中,. 表示草,而 * 表示大石。

比如这个 X=4,Y=3 的例子。

输入格式】

   第 1 行: 四个由空格隔开的整数: X, Y, Mx, My

   第 2 到第 Y+1 行: 每行包含一个由 X 个字符(. 表示草地,* 表示大石)构成的字符串,共同描绘了草地的完整地图。

【输出格式】

    输出一个整数,表示乳草完全占领草地所需要的星期数。

【样例输入】

    4 3 1 1

    ....

    ..*.

    .**.

【样例输出】

    4

【样例解释】

在草地地图中,. 表示草,而 * 表示大石   M表示已被乳草感染。

       ....   ....   MMM.   MMMM  MMMM  
       ..*.   MM*.   MM*.   MM*M  MM*M  
       M**.   M**.   M**.   M**.  M**M  
星期数  0     1       2      3      4
/**
 * @author quanran
 * @create 2021-12-05 18:14
 */
public class Milkweed {
    public static class Node {
        int row;
        int col;
        int week;
        public Node(int row, int col, int week) {
            this.row = row;
            this.col = col;
            this.week = week; // 第几个星期被感染的
        }
    }

    public static void main(String[] args) {
        //这里是获取第一行的参数
        Scanner ss = new Scanner(System.in);
        String first = ss.nextLine();
        first = first.replaceAll(" ","");
        char[] chr = first.toCharArray();
        int x = chr[0] - 48;        //表示列
        int y = chr[1] - 48;        //表示行
        int mx = chr[2] - 48 - 1;   //mx 和 my 的坐标表示第一个乳草的位置
        int my = chr[3] - 48 - 1;   // -1是因为如果输入 1,1  在我构造的数组图里 它的位置应该是 0,0 最左下角的位置
//        -------------------------------------------------------------
        int row = y;  //行
        int col = x;  //列
        //因为这个grass 第一个参数放行的话,可以直接ss.nextLine读取整行然后直接放到 grass里,很方便
        //所以干脆统一后面用到数组的地方,第一个参数都为行,第二个参数都为列
        //grass  草地
        char[][] grass = new char[row][col];
        for (int i = 0; i < row; i++) {
            String str = ss.nextLine();
            char[] cr = str.toCharArray();
            grass[i] = cr;
        }
//        -------------------------------------------------------------
        //方向数组  (行,列)
        int[][] dir = {
                {-1, 0},        // 上
                {-1, 1},        // 右上
                {0, 1},         // 右
                {1, 1},         // 右下
                {1, 0},         // 下
                {1, -1},        // 左下
                {0, -1},        // 左
                {-1, -1}        // 左上
        };
//        -------------------------------------------------------------
        //队列,用于 BFS算法
        Queue list = new LinkedList<>();
        //第一个乳草 先加进 队列里
        int frow = my;
        int fcol = mx;
        //cur 表示当前感染的位置
        Node cur = new Node(frow,fcol,0);
        list.add(cur);
//        -------------------------------------------------------------
        while (!list.isEmpty()) {
            cur = list.poll();
            //遍历每一个 cur可能会感染到的位置
            for (int i = 0; i < 8; i++) {
                //利用刚刚建立的方向数组!
                int nextrow = cur.row + dir[i][0];
                int nextcol = cur.col + dir[i][1];
                if (nextrow >= 0 && nextrow < row && nextcol >= 0 && nextcol < col && grass[nextrow][nextcol] == '.') {
                    //如果条件都通过,让这个位置感染!
                    grass[nextrow][nextcol] = 'M';
                    //把每一个感染的位置再添加进 队列 ,感染时间为下一个星期(因为一颗乳草感染其他位置,不是一下子就感染的,要用一周时间来感染完成)
                    int week = cur.week;
                    list.add(new Node(nextrow,nextcol,week + 1));
                }
            }
        }
        //最后一个弹出队列的 Node 就是最后被感染的,它的被感染时间,就是我们要的答案
        System.out.println(cur.week);
    }

}

你可能感兴趣的:(蓝桥杯,java,bfs,算法,idea)