📜  门| GATE-IT-2004 |问题 15(1)

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

题目描述

本题目为 Gate-IT-2004 的编程考试题的第15题。

给定一个由0和1组成的矩阵,每个1表示一个门,每个0表示一堵墙。我们可以将门打开,以便人员可以通过该门进入。请编写一个程序,计算每个单元格到最近门的距离。注意:在矩阵中,门可以向左、向右、向上和向下移动,但不能对角线移动,所有离门最近的距离在1以上。

输入格式

输入的第一行包含一个整数 $T$,表示测试用例的数量。每个测试用例的第一行包含两个整数 $M$ 和 $N$,它们表示矩阵的大小。接下来的 $M$ 行每行包含 $N$ 个整数,表示矩阵的单元格。

输出格式

对于每个测试用例,输出一个 $M$ 行 $N$ 列的矩阵,其中每个元素表示该元素到最近的门的距离。

示例输入

1
3 3
1 0 1
1 0 0
1 1 1

示例输出

0 1 0
0 1 1
0 0 0

解题思路

本题可以使用广度优先搜索(BFS)来解决。

将所有门的位置作为起始位置,对每个门使用BFS遍历,计算出它到每个格子的最短距离。

在遍历过程中,为了避免重复计算距离,使用一个大小与矩阵相同的visited数组记录已经遍历过的位置。

具体实现可以使用一个队列来存储待遍历的位置,遍历时按照上、下、左、右的顺序遍历。

代码实现

def bfs(mat, visited, queue):
    directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]
    while queue:
        row, col, distance = queue.pop(0)
        for dx, dy in directions:
            new_row, new_col = row + dx, col + dy
            if 0 <= new_row < len(mat) and 0 <= new_col < len(mat[0]) and not visited[new_row][new_col] and mat[new_row][new_col] == 0:
                visited[new_row][new_col] = True
                mat[new_row][new_col] = distance + 1
                queue.append((new_row, new_col, distance + 1))

def distance_to_gate(mat):
    gates = [(i, j) for i in range(len(mat)) for j in range(len(mat[0])) if mat[i][j] == 1]
    visited = [[False for _ in range(len(mat[0]))] for _ in range(len(mat))]
    for gate in gates:
        queue = [(*gate, 0)]
        visited[gate[0]][gate[1]] = True
        bfs(mat, visited, queue)
    return mat

test_cases = int(input().strip())

for _ in range(test_cases):
    m, n = map(int, input().strip().split())
    mat = [list(map(int, input().strip().split())) for _ in range(m)]
    result = distance_to_gate(mat)
    for row in result:
        print(' '.join(map(str, row)))

时间复杂度分析

本算法对于每个门都使用BFS遍历一遍整个矩阵,时间复杂度为 $O(m^2n^2)$,其中 $m$ 和 $n$ 分别为矩阵的行数和列数,因此本算法在矩阵较大时可能会超时。

空间复杂度分析

本算法使用一个大小为矩阵大小的visited数组和一个大小不会超过矩阵大小的队列,因此空间复杂度为 $O(mn)$。