7-4 迷宫-广度策略
分数 10
全屏浏览
切换布局
作者 张瑞霞
单位 桂林电子科技大学
一个陷入迷宫的老鼠如何找到出口的问题。老鼠希望系统性地尝试所有的路径之后走出迷宫。如果它到达一个死胡同,将原路返回到上一个位置,尝试新的路径。在每个位置上老鼠可以向八个方向运动,顺序是从正东开始按照顺时针进行。无论离出口多远,它总是按照这样的顺序尝试,当到达一个死胡同之后,老鼠将进行“回溯”。迷宫只有一个入口,一个出口,设计程序要求输出迷宫的一条通路。迷宫采用二维存储结构表示,1表示障碍,0表示通路;要求如下: 1、实现队列的相关操作; 2、利用队列进行广度策略搜索算法输出路径;
输入格式:
输入包括三部分: 第一个输入是迷宫大小;第二个输入是迷宫的状态;第三个输入是入口和出口位置
输出格式:
反向输出探索的路径,注意包括入口和出口位置。每个位置之间用分号;分隔。
输入样例:
9
1 1 1 1 1 1 1 1 1
1 0 0 1 1 0 1 1 1
1 1 0 0 0 0 0 0 1
1 0 1 0 0 1 1 1 1
1 0 1 1 1 0 0 1 1
1 1 0 0 1 0 0 0 1
1 0 1 1 0 0 0 1 1
1 1 1 1 1 1 1 0 1
1 1 1 1 1 1 1 1 1
1 1 7 7
输出样例:
7 7;6 6;5 6;4 5;3 4;2 3;1 2;1 1;
代码长度限制
16 KB
时间限制
400 ms
内存限制
64 MB
栈限制
8192 KB
这道迷宫问题的解题思路如下:
一、问题分析
核心要求:
1. 使用DFS(深度优先搜索)找到从入口到出口的路径
2. 老鼠可以向八个方向移动(从正东开始顺时针)
3. 需要记录并反向输出最短路径
二、数据结构设计
# 1. 迷宫表示
a = [[0] * 13 for _ in range(13)] # 存储迷宫地图(0表示通路,1表示墙)
vis = [[0] * 13 for _ in range(13)] # 记录已访问位置
# 2. 路径存储
class Point:
def __init__(self, fx=0, fy=0):
self.fx = fx
self.fy = fy
path = [Point() for _ in range(100)] # 当前路径
short_path = [Point() for _ in range(100)] # 最短路径
# 3. 方向数组(八个方向,从正东开始顺时针)
mov = [(0,1), (1,1), (1,0), (1,-1), (0,-1), (-1,-1), (-1,0), (-1,1)]
三、DFS算法实现
def dfs(x, y, step):
# 1. 到达终点时的处理
if x == end_x and y == end_y:
if step < mn: # 找到更短路径
mn = step
# 保存当前路径
for i in range(step):
short_path[i] = path[i]
return
# 2. 按顺序尝试八个方向
for i in range(8):
nx = x + mov[i][0]
ny = y + mov[i][1]
# 3. 检查新位置是否有效
if nx < 1 or nx > n or ny < 1 or ny > n:
continue
# 4. 如果是未访问的通路
if vis[nx][ny] == 0 and a[nx][ny] == 0:
# 标记访问
vis[nx][ny] = 1
# 记录路径
path[step].fx = nx
path[step].fy = ny
# 继续搜索
dfs(nx, ny, step + 1)
# 回溯:取消标记
vis[nx][ny] = 0
四、算法步骤
1. 初始化:
(1)读入迷宫大小和地图
(2)读入起点和终点坐标
(3)初始化访问数组和路径数组
2. 深度优先搜索:
(1)从起点开始,按照八个方向顺序探索
(2) 每到达一个新位置,记录在路径中
(3)如果到达终点,更新最短路径
(4)使用回溯法返回尝试其他路径
3. 路径记录:
(1)使用 `path` 数组记录当前探索路径
(2)使用 `short_path` 数组记录最短路径
(3)每找到一条更短的路径就更新 `short_path`
4. 输出结果:
(1)反向输出最短路径(从终点到起点)
(2)每个坐标之间用分号分隔
五、最终完整代码
# 全局变量
mn = 100000 # 最小步数
n = 0 # 迷宫大小
start_x = start_y = 0 # 起始位置
end_x = end_y = 0 # 结束位置
# 迷宫数组和访问标记数组
a = [[0] * 13 for _ in range(13)]
vis = [[0] * 13 for _ in range(13)]
# 路径存储
class Point:
def __init__(self, fx=0, fy=0):
self.fx = fx
self.fy = fy
path = [Point() for _ in range(100)]
short_path = [Point() for _ in range(100)]
# 八个方向:东、东南、南、西南、西、西北、北、东北
mov = [(0,1), (1,1), (1,0), (1,-1), (0,-1), (-1,-1), (-1,0), (-1,1)]
def dfs(x, y, step):
global mn
if x == end_x and y == end_y:
if step < mn:
mn = step
for i in range(step):
short_path[i].fx = path[i].fx
short_path[i].fy = path[i].fy
return
for i in range(8):
nx = x + mov[i][0]
ny = y + mov[i][1]
if nx < 1 or nx > n or ny < 1 or ny > n:
continue
if vis[nx][ny] == 0 and a[nx][ny] == 0:
vis[nx][ny] = 1
path[step].fx = nx
path[step].fy = ny
dfs(nx, ny, step + 1) # 回溯
vis[nx][ny] = 0
def main():
global n, start_x, start_y, end_x, end_y
# 输入迷宫大小
n = int(input())
# 输入迷宫状态
for i in range(n):
row = list(map(int, input().split()))
for j in range(n):
a[i][j] = row[j]
# 输入起点和终点坐标(在同一行)
coords = list(map(int, input().split()))
start_x, start_y = coords[0], coords[1]
end_x, end_y = coords[2], coords[3]
# 标记起点已访问
vis[start_x][start_y] = 1
# DFS搜索路径
dfs(start_x, start_y, 1)
# 输出路径
for i in range(mn-1, 0, -1):
print(f"{short_path[i].fx} {short_path[i].fy};", end="")
print(f"{start_x} {start_y};", end="")
if __name__ == "__main__":
main()
六、运行截图