📅  最后修改于: 2023-12-03 15:42:22.714000             🧑  作者: Mango
在一个 $n \times m$ 的网格图中,一些网格有门,其他网格没有。有一个人从某个门处出发,每秒钟可以朝上下左右四个方向走一个单位距离。当他走到有门的网格上时,就可以从那个门处继续出发。现在给定起点和终点,请问这个人能否在 $T$ 秒内到达终点。
第一行包含 4 个整数 $n,m,T,(n \leq 100,m \leq 10,T \leq 10000)$。
接下来 $n$ 行,每行包含 $m$ 个字符,其中 '.' 表示该网格为空,'#' 表示该网格有门,'S' 表示起点,'E' 表示终点。保证一个网格上最多有一个门。
输出为一行一个整数,如果能在 $T$ 秒内到达终点,输出 0,否则输出他可以到达的点中,到终点最短路长度的最大值。
5 5 10
.S...
##.#.
.#.#.
#...#
.#E#.
该问题可以用 BFS 求解。
用 $dis_{i,j}$ 表示点 $(i,j)$ 到起点的最短距离。
维护一个队列,将起点入队。
每次从队头取出一个点 $(i_0,j_0)$,
对于这个点的四个方向分别进行遍历,对于每个可以访问的点 $(i,j)$,如果 $dis_{i,j} > dis_{i_0,j_0} + 1$,则更新 $dis_{i,j}=dis_{i_0,j_0}+1$,并将这个点入队。
最后判断 $dis_{end}$ 是否小于等于 $T$,如果是,则输出 0,否则输出可以到达的点中,到终点最短路长度的最大值。
def shortestDistance(n, m, T, graph):
from collections import deque
# 存储矩阵中每个点到 start 的最短距离
distance = [[float('inf')] * m for _ in range(n)]
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
start_x = start_y = end_x = end_y = -1
for i in range(n):
for j in range(m):
if graph[i][j] == 'S':
start_x, start_y = i, j
distance[i][j] = 0
elif graph[i][j] == 'E':
end_x, end_y = i, j
q = deque([(start_x, start_y)])
while q:
x, y = q.popleft()
for i in range(4):
xx, yy = x + dx[i], y + dy[i]
if xx < 0 or xx >= n or yy < 0 or yy >= m or graph[xx][yy] == '#':
continue
if distance[xx][yy] > distance[x][y] + 1:
distance[xx][yy] = distance[x][y] + 1
q.append((xx, yy))
if distance[end_x][end_y] > T:
res = 0
for i in range(n):
for j in range(m):
if graph[i][j] == '#':
res = max(res, min(distance[i][j], T - distance[i][j]))
return res
else:
return 0
其中 n, m, T
分别为网格图的长、宽和限定时间。graph
表示网格图本身,
每个网格按照题目要求,用 .
、#
、S
、E
表示。