百练 4127 迷宫问题

求最短路问题用BFS
使用queue,到达终点即找到最短路径,即最先到达终点的路径一定是最短路径
使用字典path_dict = {}记录路径(键(当前位置):值(上一处位置)),最终通过path_dict[4, 4]一步一步地将由终点指向起点的路径存入一个list,将list逆序输出可得由[0, 0]到[4, 4]的最短路径

描述

定义一个二维数组:

int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

输入

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

输出

左上角到右下角的最短路径,格式如样例所示。

样例输入
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
样例输出
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
grid = []  # 迷宫
for _ in range(5):
    grid.append(list(input().split()))
path_dict = {}  # 字典
path_dict[0, 0] = [-1, -1]  # {(0, 0): [-1, -1]}
queue = []
queue.append([0, 0])
directions = [[-1, 0], [1, 0], [0, 1], [0, -1]]
visited = [[0 for i in range(5)] for j in range(5)]  # 0表示没走过
visited[0][0] = 1  # 从grid[0][0]起步
while len(queue):  # BFS,最先到达终点的路径一定是最短路径
    top = queue[0]  # 队首为queue[0],当前位置
    queue.pop(0)  # remove and return item at index (default last)
    if top[0] == 4 and top[1] == 4:
        tmp_list = []
        tmp_list.append([4, 4])
        next_pos = path_dict[4, 4]
        while not next_pos[0] == -1 and not next_pos[1] == -1:
            tmp_list.append([next_pos[0], next_pos[1]])
            next_pos = path_dict[next_pos[0], next_pos[1]]
        for i in range(len(tmp_list))[::-1]:
            print('({0}, {1})'.format(tmp_list[i][0], tmp_list[i][1]))
        break
    for direction in directions:
        new_r = top[0] + direction[0]
        new_c = top[1] + direction[1]
        # 没越界、没走过、非墙壁
        if new_r >= 0 and new_r < 5 and new_c >= 0 and new_c < 5 and not visited[new_r][new_c] and grid[new_r][new_c] == '0':
            path_dict[new_r, new_c] = [top[0], top[1]]  # 键(当前位置):值(上一处位置)
            visited[new_r][new_c] = 1
            queue.append([new_r, new_c])

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
迷宫问题可以使用深度优先搜索(DFS)或广度优先搜索(BFS)来解决,这里我给你提供一下DFS的Java代码。 首先定义一个迷宫类Maze,包含一个二维字符数组表示迷宫地图,起点和终点坐标的行列值,以及一个布尔类型的visited数组表示该点是否被访问过。 ```java class Maze { char[][] map; // 迷宫地图 int startRow, startCol; // 起点坐标 int endRow, endCol; // 终点坐标 boolean[][] visited; // 标记该点是否被访问过 Maze(char[][] map, int startRow, int startCol, int endRow, int endCol) { this.map = map; this.startRow = startRow; this.startCol = startCol; this.endRow = endRow; this.endCol = endCol; visited = new boolean[map.length][map[0].length]; } } ``` 下面是DFS的实现代码,使用递归的方式进行搜索。搜索过程中,先判断当前节点是否为终点,如果是,则直接返回true;否则,遍历当前节点的四个方向,如果该方向上的节点未被访问且可达,则继续递归搜索该节点。如果四个方向都搜索完毕后仍未找到解,则返回false。 ```java public boolean dfs(Maze maze, int row, int col) { // 到达终点 if (row == maze.endRow && col == maze.endCol) { return true; } // 标记该点已访问 maze.visited[row][col] = true; // 遍历四个方向 if (row > 0 && maze.map[row - 1][col] != '#' && !maze.visited[row - 1][col]) { if (dfs(maze, row - 1, col)) { return true; } } if (row < maze.map.length - 1 && maze.map[row + 1][col] != '#' && !maze.visited[row + 1][col]) { if (dfs(maze, row + 1, col)) { return true; } } if (col > 0 && maze.map[row][col - 1] != '#' && !maze.visited[row][col - 1]) { if (dfs(maze, row, col - 1)) { return true; } } if (col < maze.map[0].length - 1 && maze.map[row][col + 1] != '#' && !maze.visited[row][col + 1]) { if (dfs(maze, row, col + 1)) { return true; } } // 四个方向都搜索完毕,未找到解 return false; } ``` 最后,调用dfs方法即可得到是否存在从起点到终点的路径。 ```java char[][] map = { {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}, {'#', '.', '#', '.', '.', '.', '#', '.', '.', '#'}, {'#', '.', '#', '.', '#', '.', '#', '#', '.', '#'}, {'#', '#', '.', '.', '#', '.', '.', '.', '.', '#'}, {'#', '.', '#', '#', '.', '#', '#', '#', '.', '#'}, {'#', '.', '.', '.', '.', '.', '.', '.', '.', '#'}, {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#'} }; Maze maze = new Maze(map, 1, 1, 4, 8); // 起点(1, 1),终点(4, 8) boolean hasPath = dfs(maze, maze.startRow, maze.startCol); System.out.println(hasPath ? "存在路径" : "不存在路径"); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值