You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

63 lines
2.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
// 边权为1的时候可以使用bfs求最短路径
// 学习bfs中如何记录路径就是把bool st[N][N]修改为pair类型记录前序是哪个点
// 这样,st就不光可以记录走没走过(没走过的话值为空走过的话有PII值)而且可以通过PII反推回走的路线
#define x first
#define y second
typedef pair<int, int> PII;
const int N = 1010, M = N * N;
int n;
int g[N][N]; // 地图
PII q[M]; // 队列
PII pre[N][N]; // 前序坐标
int dx[] = {-1, 0, 1, 0}; // 上右下左
int dy[] = {0, 1, 0, -1}; // 上右下左
void bfs(int sx, int sy) {
// 将起始点初始化到队列中
int hh = 0, tt = -1;
q[++tt] = {sx, sy};
// 初始化一个不存在的值,用以区分是不是走过了
memset(pre, -1, sizeof pre);
pre[sx][sy] = {0, 0}; // 最后一个位置(n-1,n-1)只要设置一个非-1的值就描述它走过了防止重复走
while (hh <= tt) {
PII t = q[hh++];
for (int i = 0; i < 4; i++) {
int x = t.x + dx[i], y = t.y + dy[i];
if (x < 0 || x >= n || y < 0 || y >= n) continue; // 不越界
if (g[x][y]) continue; // 墙壁
if (~pre[x][y].x) continue; // 走过
// 可以走
q[++tt] = {x, y}; // 下一个要检查的坐标
pre[x][y] = t; // 从t可以走到{x,y}
}
}
}
int main() {
cin >> n;
// 本题要求左上角是(0,0)下标不能从1开始
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> g[i][j];
// 正向搜索
bfs(0, 0);
// 输出路径
vector<PII> path;
PII start = {n - 1, n - 1};
path.push_back(start);
while (true) {
if (start.x == 0 && start.y == 0) break;
start = pre[start.x][start.y];
path.push_back(start);
}
for (int i = path.size() - 1; i >= 0; i--) printf("%d %d\n", path[i].x, path[i].y);
return 0;
}