📜  门|门 CS 1997 |第 41 题(1)

📅  最后修改于: 2023-12-03 15:42:20.917000             🧑  作者: Mango

题目介绍

本题来自于北京大学的计算机科学与技术专业的课程作业。

题目描述

对于一堵墙,墙的任意一处都只可能有门或者没有门,且墙壁是连通的。现在,你需要从门出发,出门回家。请计算至少需要敲开几面墙。

输入

输入的第一行有两个正整数 $n,m$,分别表示墙的长和宽(不超过 100)。接下来 $n$ 行,每行有 $m$ 个字符。其中字符 1 表示门,字符 0 表示墙壁。

输出

输出一个整数,即至少需要敲开几面墙。

样例输入
5 5
11111
00001
11110
10000
11111
样例输出
3

解题思路

题目其实是求最短路问题,可以使用 BFS 或者 Dijkstra 算法来解决。由于本题中边权都是 1,因此 BFS 更加适合。

具体步骤:从门开始,进行 BFS 搜索,每到达一个相邻的墙的位置,就将其标记为已经搜索过,并记录到达该位置的步数。

最后,我们就可以得到从门到每个点的最短路径,其中最大的路径长度就是最少需要敲开的墙的数量。

代码实现

from queue import Queue

n, m = map(int, input().split())

matrix = []
for i in range(n):
    matrix.append(list(map(int, list(input().strip()))))

# 初始位置
start = (0, 0)
for i in range(n):
    for j in range(m):
        if matrix[i][j] == 1:
            start = (i, j)

# 定义四个方向
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]

visited = [[False for _ in range(m)] for _ in range(n)]
q = Queue()
q.put(start)

# 记录初始位置
visited[start[0]][start[1]] = True
step = [[0 for _ in range(m)] for _ in range(n)]

while not q.empty():
    x, y = q.get()
    for i in range(4):
        a, b = x + dx[i], y + dy[i]
        if 0 <= a < n and 0 <= b < m and not visited[a][b] and matrix[a][b] == 0:
            visited[a][b] = True
            step[a][b] = step[x][y] + 1
            q.put((a, b))

max_step = 0
for i in range(n):
    for j in range(m):
        if matrix[i][j] == 0 and visited[i][j]:
            max_step = max(max_step, step[i][j])

print(max_step)

上面的代码使用了 Python 语言,在输入方面,我们使用最基本的 input() 函数进行输入读取,在 BFS 方面,我们使用了 Python 的 queue 库中的队列实现,非常方便。