📅  最后修改于: 2023-12-03 15:28:49.091000             🧑  作者: Mango
在 ACM/ICPC 门松向祥的 CS 部门 的 2012 年训练赛中,有一道题目叫做“门”。
题目描述:
有一幢 $N\times M$ 的建筑,其中有些位置有门,其余位置为墙。现在需要从左上角走到右下角,并且只能走门连接的位置。求出从左上角到右下角的最短路径长度。
输入格式:
第 1 行两个整数 $N$ 和 $M$,表示建筑的行数和列数。
接下来 $N$ 行,每行 $M$ 个字符,表示该位置的状态。其中 $’.’$ 表示墙,$’#’$ 表示门。
输出格式:
一个整数,表示从左上角到右下角的最短路径长度。如果无法到达,输出 $-1$。
具体例子可以看这里。
这道题目可以使用 BFS 等算法来解决。具体实现过程可以用一个队列来维护当前可以到达的位置,采用 BFS 进行搜索。对于每个门对应的位置,需要将其所有可以到达的位置入队,并将其 G 值(即距离起点的步数)加一。具体过程如下:
queue<pair<int, int>> q;
int g[N][M];
q.push({0, 0});
g[0][0] = 0;
while (!q.empty()) {
auto t = q.front();
q.pop();
int x = t.first, y = t.second;
if (x == n - 1 && y == m - 1) return g[x][y];
for (int i = 0; i < 4; i++) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < n && b >= 0 && b < m && s[a][b] != '#' && g[a][b] == -1) {
g[a][b] = g[x][y] + 1;
q.push({a, b});
}
}
}
return -1;
#include <iostream>
#include <cstring>
using namespace std;
const int N = 1e2+10;
const int dx[4] = {-1, 1, 0, 0}, dy[4] = {0, 0, -1, 1};
int n, m;
char s[N][N];
int g[N][N];
int bfs() {
queue<pair<int, int>> q;
memset(g, -1, sizeof g);
q.push({0, 0});
g[0][0] = 0;
while (!q.empty()) {
auto t = q.front();
q.pop();
int x = t.first, y = t.second;
if (x == n - 1 && y == m - 1) return g[x][y];
for (int i = 0; i < 4; i++) {
int a = x + dx[i], b = y + dy[i];
if (a >= 0 && a < n && b >= 0 && b < m && s[a][b] != '#' && g[a][b] == -1) {
g[a][b] = g[x][y] + 1;
q.push({a, b});
}
}
}
return -1;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> s[i];
cout << bfs() << endl;
return 0;
}
以上是本人的程序实现,如果有疑问欢迎交流。