题解 | #迷宫问题#

迷宫问题

http://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc

与其说分享解题思路,不如说是小白的吐苦水。

本题选择用 DFS 来做,先是思考了下构建 DFS 的结构:

  • 目标是到达终点,同时记录路径,最后选择最短路径输出,所以需要记录路径的变量记录最短路径的变量记录路径长度和最短长度的变量。其他变量则看 dfs 实现的风格了而设置了。

  • 设置 dfs 的出口,根据目标,出口1 就是到达终点,这时就需要来判断该路径是否最短; 出口 2 就是此路不通。

  • 所以其他情况就代表在路上,假设位于 x,y 处,你有四个方向可以前进,但需要排除你来时的路,所以可以将走过的路做标记,比如设置其为-1或者其他数,表示走过。

上面情况讲清楚了,接下来就是实现了,dfs 的特点就是除了出口外对于每一点的处理都是相似的,所以需要总结处理特点,对于下一步的处理有两种方法,①是直接判断下一点是否可达,②是先进入下一点,再判断是否可达::我用的第二种,不太聪明的亚子

  • 假设位于 x,y 处,现在要先判断该点是否为终点,是否该点不通或已走过,如果是个可达点,记录该点到路径变量中,然后设置该点的值为 -1,表示来过,然后就是进入下一点,有四种可能,(x+1,y), (x-1,y), (x,y+1), (x,y-1), 这四个方向都有可能到达终点,所以对这四种可能进行 或 运算。
  • 走完四种可能性要将假设中走过的路径恢复,即把设置为-1的点重新设置为 0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int trace[100][2] = {0},        // 记录路径
    min_trace[100][2] = {0};          // 记录最短路径
int maze[10][10];              // 迷宫
// int curStep = 0;               // 表示当前前进的步数,也是最终的路径长度
int minStep = 100;               // 最短路径
int flag = 0;

int findTrace(int curXidx, int curYidx, int row, int col, int curStep);

int main() {
    int row, col;
    while (scanf("%d %d", &row, &col) != EOF) {
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                scanf("%d", &maze[i][j]);
            }
        }
        flag = findTrace(0, 0, row, col, 0);
        if (flag == -1) {
            printf("ERROR\n");
        } else {
            for (int i = 0; i <= minStep; i++) {
                printf("(%d,%d)\n", min_trace[i][0], min_trace[i][1]);
            }
        }
    }
    return 0;
}

int findTrace(int curXidx, int curYidx, int row, int col, int curStep) {
    
    int f = 0;
    // 到达终点
    if (curXidx == row - 1 && curYidx == col - 1) {
        trace[curStep][0] = curXidx;
        trace[curStep][1] = curYidx;
        if (curStep < minStep) {	// 复制最短路径
            minStep = curStep;
            for (int i = 0; i <= minStep; i++) {
                min_trace[i][0] = trace[i][0];
                min_trace[i][1] = trace[i][1];
            }
        }
        return 1;
    }
    // 该点可达
    if ((curXidx >= 0 && curXidx < row ) &&
            (curYidx >= 0 && curYidx < col) &&
            (maze[curXidx][curYidx] == 0)) {
        
        trace[curStep][0] = curXidx;
        trace[curStep][1] = curYidx;
        ++curStep;
        
        maze[curXidx][curYidx] = -1;    // 表示走过
      
        f = findTrace(curXidx + 1, curYidx, row, col, curStep) ||
            findTrace(curXidx, curYidx + 1, row, col, curStep) ||
            findTrace(curXidx, curYidx - 1, row, col, curStep) ||
            findTrace(curXidx - 1, curYidx, row, col, curStep);
      
        maze[curXidx][curYidx] = 0;    // 恢复
        
    } 
  	// 此路不通
    else {
        return 0;
    }
    return f;
}
全部评论
不太看得懂恢复的那一步有什么意义,仅仅往前面回溯了一个点,且已经跳出了递归的过程,后面的都是顺序执行了。去掉恢复的那一步运行结果是一样的
点赞 回复 分享
发布于 2022-12-19 19:14 四川
题目不是说了迷宫只有一条通道吗,为什么还要记录最短路径?
点赞 回复 分享
发布于 2022-12-25 17:12 新加坡
逻辑||左边为真不再进行右边的判断;所以如果想要找到全部路径,四个findTrace都要执行一遍。 f = findTrace(curXidx + 1, curYidx, row, col, curStep) || findTrace(curXidx, curYidx + 1, row, col, curStep) || findTrace(curXidx, curYidx - 1, row, col, curStep) || findTrace(curXidx - 1, curYidx, row, col, curStep);
点赞 回复 分享
发布于 2023-02-21 09:16 山东

相关推荐

点赞 评论 收藏
分享
浪子陪都:简历最优秀的地方放到了后面,国奖,校级奖学金这些是最亮眼的。说明你跟同级别的学生不一样。 建议台灯这个,PCB布局布线这个词汇不专业,业内是PCB Layout,第二,单片机的板子一般不用考虑SI,PI 都是低速信号,只要遵循3W原则就好了。 单片机的项目太low了,技能这块,你要看一下BOSS直聘的招聘要求,按照别人的要求写,一些关键词可以增加你简历被检索到的概率。 主修课程不用写,这个没有人去关注的。
点赞 评论 收藏
分享
评论
17
9
分享

创作者周榜

更多
牛客网
牛客企业服务