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

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

题目描述

本题题目是“门|门 CS 1997”,是一个计算机科学竞赛题目。这道题的题号是第45题。

题目详情

这道题目的具体描述是:

在一个M*N的格子地图上,有若干个门和石墙。门可以连接两个不同的格子,石墙则是障碍物,不能通过。现在你需要求出两个给定的门之间的最短路径长度。

解题思路

本题的解法相对来说比较简单,可以用经典的 graph 的解法:利用 BFS(Breadth First Search,宽度优先搜索)算法求解最短路径。

BFS 算法的基本思路是:

  1. 搜索起点入队列
  2. 出队列一个元素,并访问之
  3. 将入度之外的所有未访问元素入队列
  4. 如果对于所需的搜索目标,搜到了,直接结束算法

我们可以将整个地图看作一个 $M \times N$ 的网格,每个格子是一个结点,门之间形成了一堆边。将整个地图看作一个 graph(图),利用 BFS 算法求解最短距离即可。

在实现 BFS 算法时,我们需要维护以下几个变量:

  1. 见过的结点
  2. 从开始结点到某一结点的距离
  3. 在 process 中的每个结点
  4. 路径前缀

代码实现

def bfs(graph, start, end):
    # visited 存储已经遍历过的节点,防止重复访问
    visited = set()

    # queue 存储以加入的节点,起到 bfs 的作用
    queue = [[start]]

    # 如果找到end,直接返回到此为止的遍历过的所有节点
    if start == end:
        return queue

    while queue:
        path = queue.pop(0)

        # 取出当前路径的最后一个结点,然后进行 BFS 接下来的操作
        node = path[-1]

        if node not in visited:
            neighbors = graph[node]

            # 遍历未访问的邻居结点,并在前缀路径基础上添加相邻结点,并将其入队
            for neighbor in neighbors:
                new_path = list(path)
                new_path.append(neighbor)

                queue.append(new_path)

                # 如果相邻结点就是终点,直接返回路径
                if neighbor == end:
                    return new_path

            # 标记此点为已访问
            visited.add(node)

    # 如果循环结束,但是始终没有找到到达终点的路径
    raise Exception("Path not found!")

代码片段已按 markdown 标明。