件名アドレス:
https://www.acwing.com/problem/content/1078/
与えられたn×nn×nn××nの2次元配列は次のとおりです。
int maze[5][5] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
それは迷路を表しており、1 11は壁を意味し、000は歩くことができることを意味し、斜めではなく水平または垂直にしか歩くことができません。左上隅から右下隅までの最短ルートを見つけるためのプログラミングが必要です。データは、左上隅から右下隅へのパスが少なくとも1つあることを保証します。
入力形式:
最初の行には整数nnが含まれていますn。次のnnn行、各行にはnnが含まれますn整数000または111、これは迷路を意味します。
出力形式:
左上隅から右下隅までの最短ルートを出力します。答えが一意でない場合は、任意のパスを出力します。順番に、各行はパスを通過するセルの座標を出力し、左上隅の座標は(0、0)(0,0)です。(0 、0 )、右下隅の座標は(n − 1、n − 1)(n−1、n−1)(n − 1 、n − 1 )。
データ範囲:
0≤n≤10000≤n≤10000≤n≤1 0 0 0
両側は11です1. BFSを使用して最短パスを見つけ、配列ppを使用できます。pを保存するp [i] [j] p [i] [j]p [ i ] [ j ]このグリッドはどのグリッドから来たのですか?パスを見つけるときは、終点から始点まで押します。便宜上、終点(n − 1、n − 1)(n-1、n-1)から直接開始することもできます。(n−1 、n−1 )検索を開始し、開始点を見つけます(0、0)(0,0)(0 、0 )、したがって、パスが(0、0)(0,0)から推定される場合(0 、0 )相殺されます。コードは次のように表示されます。
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 1010, d[] = {
1, 0, -1, 0, 1};
int n;
int a[N][N];
pair<int, int> pre[N][N];
queue<pair<int, int> > q;
void bfs(int x, int y) {
q.push({
x, y});
// 未访问的点设为-1
memset(pre, -1, sizeof pre);
pre[x][y] = {
x, y};
while (!q.empty()) {
auto t = q.front();
q.pop();
x = t.first, y = t.second;
for (int i = 0; i < 4; i++) {
int nx = x + d[i], ny = y + d[i + 1];
// 出界了,略过
if (nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
// 略过障碍物
if (a[nx][ny]) continue;
// 访问过,则略过
if (pre[nx][ny].first != -1) continue;
q.push({
nx, ny});
pre[nx][ny] = t;
// 搜到起点了,可以直接退出
if (nx == 0 && ny == 0) return;
}
}
}
int main() {
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &a[i][j]);
bfs(n - 1, n - 1);
pair<int, int> end = {
0, 0};
while (1) {
printf("%d %d\n", end.first, end.second);
if (end.first == n - 1 && end.second == n - 1) break;
end = pre[end.first][end.second];
}
return 0;
}
時間と空間の複雑さO(n 2)O(n ^ 2)O (n2)。