📅  最后修改于: 2023-12-03 15:42:20.855000             🧑  作者: Mango
这是一个算法问题,出自 1996 年清华大学计算机科学与技术专业的《计算机科学》考试中。问题需要求解的是,在一个由若干个门组成的迷宫中,从一个门到另一个门的最短路径长度。
假设迷宫是一个 $n$ 行 $m$ 列的矩阵,其中门用 $1$ 表示,空地用 $0$ 表示。给定两个不同的门的坐标 $(x_1, y_1)$ 和 $(x_2, y_2)$,请计算从第一个门到第二个门的最短路径长度。
第一行包含三个整数 $n,m,q$,表示迷宫的大小以及询问数量。
接下来 $n$ 行,每行 $m$ 个整数,用空格隔开,表示迷宫。其中 $0$ 表示空地,$1$ 表示门。
接下来 $q$ 行,每行包含 $4$ 个整数 $x_1,y_1,x_2,y_2$,表示一组询问。
对于每一个询问,输出一个整数,表示从第一个门到第二个门的最短路径长度,如果不存在合法的路径,则输出 $-1$。
本题可以使用广度优先搜索 (BFS) 求解,具体思路如下:
首先对迷宫顶点进行编号,方便存储和查找。
对每一组询问,都进行一次 BFS,求出从起点到终点的最短路径长度。
具体实现中,可以使用一个队列来存储待遍历的顶点,同时记录每个顶点的层数,用一个数组来存储已经访问过的顶点,避免重复访问。
下面给出一个简单的 Python 实现,时间复杂度为 $O(qmn)$。在实现中,为了代码简洁,省略了一些异常处理和边界判断。
from collections import deque
# 迷宫顶点编号
def vertex(x, y):
return x * m + y
# BFS 搜索
def bfs(s, t):
q = deque([(s, 0)])
visited[s] = True
while q:
v, d = q.popleft()
x, y = divmod(v, m)
if v == t:
return d
for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
nx, ny = x + dx, y + dy
if 0 <= nx < n and 0 <= ny < m and not visited[vertex(nx, ny)] and maze[nx][ny] == 0:
visited[vertex(nx, ny)] = True
q.append((vertex(nx, ny), d + 1))
return -1
n, m, q = map(int, input().split())
maze = [list(map(int, input().split())) for i in range(n)]
for i in range(q):
x1, y1, x2, y2 = map(int, input().split())
s, t = vertex(x1-1, y1-1), vertex(x2-1, y2-1)
visited = [False] * (n*m)
print(bfs(s, t))
本题考察了对 BFS 搜索算法的理解和应用,同时也需要一定的编程基础。对于初学者来说,可以通过更简单的问题逐步深入学习。对于有一定编程经验的同学,这道题也是一个不错的练习题目。