题目描述:
给定一个 n×n 的二维数组,如下所示:
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表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
数据保证至少存在一条从左上角走到右下角的路径。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含 n 个整数 0 或 1,表示迷宫。
输出格式
输出从左上角到右下角的最短路线,如果答案不唯一,输出任意一条路径均可。
按顺序,每行输出一个路径中经过的单元格的坐标,左上角坐标为 (0,0),右下角坐标为 (n−1,n−1)。
数据范围
0≤n≤1000
输入样例:
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
输出样例:
0 0
1 0
2 0
2 1
2 2
2 3
2 4
3 4
4 4
分析:利用BFS求最短路径的问题,这道题难点在于输出路径吧,之前碰到的只需要输出长度,利用一个pre数组,记录下当前节点是由哪个节点过来的,然后从终点倒着输出一遍即可。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef pair<int,int> PII;
const int N = 1010;
int n ;
int g[N][N];
PII pre[N][N];
PII q[N*N];
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};
int dx[] = {-1,1,0,0} , dy[]={0,0,-1,1};
while( hh <= tt)
{
PII t = q[hh++];
for(int i = 0 ; i < 4 ; i ++)
{
int a = t.first + dx[i] , b = t.second + dy[i];
if( a < 0 || a >= n || b < 0 || b >= n) continue;
if(g[a][b] == 1) continue;
if(pre[a][b].first != -1)continue;
q[++tt] = {a,b};
pre[a][b] = t;
}
}
}
int main(){
cin >> n;
for(int i = 0 ; i < n ; i ++)
for(int j = 0 ; j < n ; j++)
cin >> g[i][j];
bfs( n - 1, n - 1);
PII end(0,0);
while( end.first != n- 1 || end.second != n -1)
{
printf("%d %d\n",end.first,end.second);
end = pre[end.first][end.second];
}
printf("%d %d\n",end.first,end.second);
return 0;
}