美文网首页
作者在“拯救大兵瑞恩”时遇到的问题小记——迷宫最短路径

作者在“拯救大兵瑞恩”时遇到的问题小记——迷宫最短路径

作者: 进击的NULL | 来源:发表于2018-12-28 16:00 被阅读0次

    问题描述

    约翰·米勒上尉接到上级命令,要去一个迷宫拯救被困其中的大兵瑞恩。迷宫由空地格子和障碍物——墙组成。现在米勒从(1,1)这个地方降落并进入迷宫,问找到瑞恩的最短路径。通过卫星定位到瑞恩所在坐标为(p, q)处,让你求解。

    代码

    /**
     * 约翰·米勒上尉接到上级命令,要去一个迷宫拯救被困其中的大兵瑞恩。
    *迷宫由空地格子和不可穿透的墙组成。现在米勒从(1,1)这个地方降落并进入迷宫,问找到瑞恩的最短路径。
    *通过卫星定位到瑞恩所在坐标为(p, q),让你求解。
     * @author XZP
     *
     */
    public class SavingToRyan {
        // 给定一个迷宫,1表示墙,0表示空地
        public static int[][] maze = {
                {0, 0, 1, 0},
                {0, 0, 0, 0},
                {0, 0, 1, 0},
                {0, 1, 0, 0},
                {0, 0, 0, 1}
        };
        // 初始化一个控制方向的向量
        public static int[][] direction = {
                {0, 1}, // 左
                {1, 0}, // 下
                {0, -1}, // 右
                {-1, 0}  // 上
        };
        public static int[][] book = new int[5][4]; // 用于标记该格子是否走过
        // 迷宫的行列
        public static int row = 5;
        public static int col = 4;
        // 米勒出发的坐标x,y
        public static int startx = 1; 
        public static int starty = 1;
        // 瑞恩被困的位置p,q
        public static int p = 4;
        public static int q = 3;
        // 初始化一个全局变量保存最短路径
        public static int min = Integer.MAX_VALUE;
        public static void main(String[] args) {
            book[0][0] = 1;
            dfs(1, 1, 0);
            System.out.println("救出瑞恩的最短路径为:" + min);
        }
        public static void dfs(int x, int y, int step) {
            int nx, ny;
            // 首先是当前的状态
            if (x == p && y == q) { // 找到瑞恩
                if (step < min) {
                    min = step;
                    System.out.println("x:" + x + " y:" + y + " p:" + p + " q:" + q + " step:" + step);
                }
                return;
            }
            System.out.println("x:" + x + " y:" + y);
            for (int k = 0; k < 4; k++) {
                nx = x + direction[k][0]; // 下一步的x,y值
                ny = y + direction[k][1];
                if (nx < 1 || nx > 5 || ny < 1 || ny > 4) {
                    continue;
                }
                if (book[nx-1][ny - 1] == 0 && maze[nx - 1] [ny -1] == 0) { // 在迷宫内且没有障碍物,没有走过
                    book[nx - 1][ny -1] = 1; // 这步很重要,如果没有就会栈溢出 ----------------------------     (1)
                    dfs(nx, ny, step + 1);
                    book[nx - 1][ny - 1] = 0; // 回退到这步要将其重新标记为能走的  ----------------------- (2)
                }
            }
        }
    }
    
    

    注意

    作者因为一时疏忽,漏掉了注释(1)处对应的那行代码,于是测试的时候栈溢出,反复理了一下逻辑,都觉得没问题,再三跟踪调试之后,发现自己犯了一个低级错误:死递归。
    如果不要注释(1)对应的代码,就会在下一步的格子中递归回来(这个应该比较好理解),如此往复!
    那顺带说一下注释(2)对应的代码,就是尝试完(nx-1, ny - 1)对应的点之后需要将这个标记拿掉。有点绕,很多问题在这两步时最难理解!!!!故特别记录,以便加深自己的理解和运用。

    相关文章

      网友评论

          本文标题:作者在“拯救大兵瑞恩”时遇到的问题小记——迷宫最短路径

          本文链接:https://www.haomeiwen.com/subject/rffelqtx.html