我的解题核心主要是 BFS
关键字
“最少时间”, 人每移动一个单位花费一个单位时间, 火也是一样的
解题思路
首先, BFS计算出火势蔓延全部迷宫的时间数组 fire_time, 也就是火势蔓延到每一位置的时间
使用二维数组表示, fire_time表示
然后, 使用BFS搜索出人的逃生, 每次做出动作之前,要判断,到达下一个区域所需
的总时间,是不是比火势蔓延到该区域的时间少,如果人行动的时间少于火势蔓延
的时间,那么就可以做出这个动作
最后,当来到边界的时候,就是方案,否则无法逃生
准备条件
1、迷宫数组 mg
用来存迷宫的数据
2、初始的起火点 fire
用来存放开始的时候,就已经起火的位置,题目没有说明只有一处起火点,通过
试错,发现不一定只有一处起火点
3、火势蔓延时间数组 fire_time
用来存放各个可以被火势蔓延到的点, 当火势蔓延到那一位置的时间
4、火势广度优先搜索函数 bfs_fire_time
用来搜索出各个点的火势蔓延时间
5、人逃生广度优先搜索函数 bfs_people
用来搜索出人逃生的最佳方案, bfs搜索出来的就是最佳方案
注意点
1、当某一个点可以作为下一次的逃生位置的是后, 还要考虑逃生到那里之后
火势是不是正好蔓延到那里, 在代码中体现为 fire_time_list[nx][ny] > value + 1
2、使用sys的stdin.read(),不然可能超时
from collections import deque
dx = [-1, 1, 0, 0]
dy = [0, 0, -1, 1]
def bfs_fire_time(fire_init, mg, n, m):
fire_time_list = [[float('inf')] * m for _ in range(n)]
q = deque()
for tu in fire_init:
fire_time_list[tu[0]][tu[1]] = 0
q.append(tu)
while q:
x, y = q.popleft()
for i in range(4):
nx, ny = x + dx[i], y + dy[i]
if 0 <= nx < n and 0 <= ny < m and mg[nx][ny] != "#":
if fire_time_list[nx][ny] > fire_time_list[x][y] + 1:
fire_time_list[nx][ny] = fire_time_list[x][y] + 1
q.append((nx, ny))
return fire_time_list
def bfs_poeple(start_point, mg, n, m, fire_time_list):
q = deque([(start_point[0], start_point[1], 0)])
visited = [[False] * m for _ in range(n)]
visited[start_point[0]][start_point[1]] = True
while q:
x, y , value = q.popleft()
if 0 == x or x == n - 1 or y == 0 or y == m -1:
return value + 1
for i in range(4):
nx, ny = x + dx[i], y + dy[i]
if 0 <= nx < n and 0 <= ny < m and not visited[nx][ny]:
if mg[nx][ny] != "#" and fire_time_list[nx][ny] > value + 1:
visited[nx][ny] = True
q.append((nx, ny, value + 1))
return "IMPOSSIBLE"
if __name__ == "__main__":
import sys
input = sys.stdin.read().split()
prt = 0
T = int(input[prt])
prt += 1
for _ in range(T):
n, m = int(input[prt]), int(input[prt + 1])
prt += 2
mg = [input[prt + i] for i in range(n)]
prt += n
pp = None
fire = []
for i in range(n):
for j in range(m):
if mg[i][j] == "J":
pp = (i, j)
elif mg[i][j] == "F":
fire.append((i, j))
fire_time = bfs_fire_time(fire, mg, n, m)
res = bfs_poeple(pp, mg, n, m, fire_time)
print(res)