📅  最后修改于: 2023-12-03 15:28:46.640000             🧑  作者: Mango
本题是 Sudo GATE 2020 Mock III(2019 年 1 月 24 日)中的第 48 题,题目描述如下:
给定一个二进制矩阵,其中 0 表示门的位置,1 表示墙的位置。从左上角的门出发开始遍历矩阵,每次可以向上、向下、向左或向右移动,但不能穿过墙,求离门最远的格子到门的距离。
例如,给定以下矩阵:
0 1 1 1 1
1 1 1 1 1
1 1 0 1 1
1 1 1 1 1
1 1 1 1 0
从左上角的门出发,离门最远的格子到门的距离为 6,如下所示:
0 1 1 1 1
1 2 3 4 5
2 3 0 5 6
3 4 5 6 7
4 5 6 7 0
这道题可以使用广度优先搜索(BFS)来解决。从门的格子出发,每次找出当前格子相邻的一组格子,并把它们加入到队列中,然后标记已经访问过的格子,并记录当前格子到门的距离。
在每一轮中,先把队列中的元素全部取出,并把它们相邻的一组格子加入到队列中。标记访问过的格子时,可以使用一个额外的 visit 矩阵来记录。在访问过的格子不需要重新加入队列。
在所有的格子都被访问完之后,返回到离门最远的格子的距离即可。
下面是 Python 代码的实现,其中 dfs 函数是用来遍历相邻格子的:
def dfs(grid, i, j, dist, visit):
queue = []
queue.append((i, j))
visit[i][j] = True
while queue:
ii, jj = queue.pop(0)
d = dist[ii][jj] + 1
for x, y in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
ni, nj = ii + x, jj + y
if ni >= 0 and ni < len(grid) and nj >= 0 and nj < len(grid[0]) and grid[ni][nj] == 0 and not visit[ni][nj]:
visit[ni][nj] = True
dist[ni][nj] = d
queue.append((ni, nj))
def door_distance(grid):
if not grid or not grid[0]:
return 0
n, m = len(grid), len(grid[0])
visit = [[False] * m for _ in range(n)]
dist = [[0] * m for _ in range(n)]
for i in range(n):
for j in range(m):
if grid[i][j] == 0 and not visit[i][j]:
dfs(grid, i, j, dist, visit)
return max([dist[i][j] for i in range(n) for j in range(m)])
代码页面展示效果:
def dfs(grid, i, j, dist, visit):
queue = []
queue.append((i, j))
visit[i][j] = True
while queue:
ii, jj = queue.pop(0)
d = dist[ii][jj] + 1
for x, y in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
ni, nj = ii + x, jj + y
if ni >= 0 and ni < len(grid) and nj >= 0 and nj < len(grid[0]) and grid[ni][nj] == 0 and not visit[ni][nj]:
visit[ni][nj] = True
dist[ni][nj] = d
queue.append((ni, nj))
def door_distance(grid):
if not grid or not grid[0]:
return 0
n, m = len(grid), len(grid[0])
visit = [[False] * m for _ in range(n)]
dist = [[0] * m for _ in range(n)]
for i in range(n):
for j in range(m):
if grid[i][j] == 0 and not visit[i][j]:
dfs(grid, i, j, dist, visit)
return max([dist[i][j] for i in range(n) for j in range(m)])