📜  门| GATE CS 2021 |设置 2 |第 53 题(1)

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

门| GATE CS 2021 |设置 2 |第 53 题

这是 GATE CS 2021 设置 2 中的第 53 题,要求编写一个程序,实现以下功能:

给定一个由 '1' 和 '0' 组成的矩阵,其中 '1' 表示墙壁,'0' 表示空地。矩阵中可能存在围墙,从 (0,0) 开始,求到所有空地区域的最短距离。

以下是该题的要求和思路:

要求

给定一个由 '1' 和 '0' 组成的矩阵,其中 '1' 表示墙壁,'0' 表示空地。矩阵中可能存在围墙,从 (0,0) 开始,求到所有空地区域的最短距离。

输入格式:

  • 第一行包含两个正整数 m 和 n,表示矩阵的行数和列数。
  • 接下来 m 行,每行包含 n 个字符,表示矩阵中的一行。

输出格式:

  • 输出 m 行,每行包含 n 个整数,表示从 (0,0) 到矩阵中对应位置的最短距离。如果该位置不可达,则输出 -1。
思路

首先我们需要定义一个 BFS 函数来对矩阵进行遍历并求解最短距离。然后从起点开始,对其进行广度优先搜索(BFS)。

通过 BFS,可以得到从起点到各个位置的最短距离。对于起点来说,其到自己的距离为 0,从而可以将其入队。接着,从队列中取出队首元素,分别遍历其周围的四个方向(上、下、左、右),如果这些方向的位置非墙且当前位置的距离大于等于从起点到队首位置的距离加一(即通过队首到达该位置的距离),则将该位置入队,并更新该位置的距离。

最后,遍历整个矩阵,将每个位置到起点的最短距离输出即可。

以下是该题的参考代码,使用 C++ 语言编写:

#include <iostream>
#include <vector>
#include <queue>
using namespace std;

const int INF = 1e9; // 表示最大距离

// BFS 函数
void bfs(vector<vector<int>>& mat, int n, int m) {
    vector<vector<int>> dist(n, vector<int>(m, INF)); // 存储每个位置到起点的最短距离
    dist[0][0] = 0; // 起点到自己的距离为 0
    queue<pair<int, int>> q; // 存储 BFS 遍历过程中的位置
    q.push({0, 0});
    while (!q.empty()) {
        auto p = q.front(); // 取出队首元素
        q.pop();
        int x = p.first, y = p.second;
        if (x > 0 && mat[x-1][y] == 0 && dist[x-1][y] > dist[x][y]+1) { // 上方的位置
            dist[x-1][y] = dist[x][y]+1;
            q.push({x-1, y});
        }
        if (x < n-1 && mat[x+1][y] == 0 && dist[x+1][y] > dist[x][y]+1) { // 下方的位置
            dist[x+1][y] = dist[x][y]+1;
            q.push({x+1, y});
        }
        if (y > 0 && mat[x][y-1] == 0 && dist[x][y-1] > dist[x][y]+1) { // 左边的位置
            dist[x][y-1] = dist[x][y]+1;
            q.push({x, y-1});
        }
        if (y < m-1 && mat[x][y+1] == 0 && dist[x][y+1] > dist[x][y]+1) { // 右边的位置
            dist[x][y+1] = dist[x][y]+1;
            q.push({x, y+1});
        }
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j] == 1) cout << "-1 "; // 墙不可达
            else if (dist[i][j] == INF) cout << "-1 "; // 不可达
            else cout << dist[i][j] << " ";
        }
        cout << endl;
    }
    return;
}

// 主函数
int main() {
    int n, m;
    cin >> n >> m;
    vector<vector<int>> mat(n, vector<int>(m));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            char c;
            cin >> c;
            mat[i][j] = c-'0';
        }
    }
    bfs(mat, n, m);
    return 0;
}

在该代码中,我们首先定义了一个二维矩阵(即存储图),然后通过 BFS 函数进行遍历,最后输出矩阵中每个位置到起点的最短距离。在 BFS 函数中,我们使用了一个二维向量来存储每个位置到起点的最短距离,注意这里的最短距离表示的是通过操作(即从一个点到达另一个点)得到的距离。

该函数的时间复杂度为 O(nm),其中 n 和 m 分别是矩阵的行数和列数。在实际应用中,该算法可以用于解决某些迷宫问题。