给定一个 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
记录方法1:从终点开始bfs,维护一个该点是由谁扩展来的,从起点逐个输出就行了 PII pre[N][N];
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
typedef pair<int,int>PII;
int n;
int g[N][N];
int dist[N][N];
PII q[N*N];
PII pre[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,1,-1};
void bfs(int x,int y)
{
int tt=-1,hh=0;
q[++tt]={x,y};
memset(dist,-1,sizeof dist);
dist[x][y]=0;
while(hh<=tt)
{
auto t=q[hh++];
int x1=t.first,y1=t.second;
for(int i=0;i<4;i++)
{
int temx1=x1+dx[i],temy1=y1+dy[i];
if(temx1<0||temx1>=n||temy1<0||temy1>=n)continue;
if(dist[temx1][temy1]!=-1||g[temx1][temy1])continue;
dist[temx1][temy1]=dist[x1][y1]+1;
pre[temx1][temy1]={x1,y1};
q[++tt]={temx1,temy1};
}
}
}
void dfs(int x,int y)
{
if(x==0&&y==0)
{
printf("0 0\n");
return;
}
dfs(pre[x][y].first,pre[x][y].second);
cout<<x<<" "<<y<<endl;
}
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 ed={0,0};
while(1)
{
printf("%d %d\n",ed.first,ed.second);
if(ed.first==n-1&&ed.second==n-1)break;
ed=pre[ed.first][ed.second];
}
}
记录方法2:从源点bfs,维护pre dfs输出就行
#include<bits/stdc++.h>
using namespace std;
const int N=1010;
typedef pair<int,int>PII;
int n;
int g[N][N];
int dist[N][N];
PII q[N*N];
PII pre[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,1,-1};
void bfs(int x,int y)
{
int tt=-1,hh=0;
q[++tt]={x,y};
memset(dist,-1,sizeof dist);
dist[x][y]=0;
while(hh<=tt)
{
auto t=q[hh++];
int x1=t.first,y1=t.second;
for(int i=0;i<4;i++)
{
int temx1=x1+dx[i],temy1=y1+dy[i];
if(temx1<0||temx1>=n||temy1<0||temy1>=n)continue;
if(dist[temx1][temy1]!=-1||g[temx1][temy1])continue;
dist[temx1][temy1]=dist[x1][y1]+1;
pre[temx1][temy1]={x1,y1};
q[++tt]={temx1,temy1};
}
}
}
void dfs(int x,int y)
{
if(x==0&&y==0)
{
printf("0 0\n");
return;
}
dfs(pre[x][y].first,pre[x][y].second);
cout<<x<<" "<<y<<endl;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
cin>>g[i][j];
bfs(0,0);
// PII ed={0,0};
// while(1)
// {
// printf("%d %d\n",ed.first,ed.second);
// if(ed.first==n-1&&ed.second==n-1)break;
// ed=pre[ed.first][ed.second];
// }
// printf("%d %d",pre[n-1][n-1].first,pre[n-1][n-1].second);
dfs(n-1,n-1);
}