题意
给定一个5*5的二维数组,0代表可以走,1代表不可以走。
输出从左上角(0,0)走到右下角(4,4)的路径。(保证有唯一解)
样例
样例输入:
0 1 0 0 0
0 1 0 1 0
0 1 0 1 0
0 0 0 1 0
0 1 0 1 0
样例输出:
(0, 0)
(1, 0)
(2, 0)
(3, 0)
(3, 1)
(3, 2)
(2, 2)
(1, 2)
(0, 2)
(0, 3)
(0, 4)
(1, 4)
(2, 4)
(3, 4)
(4, 4)
思路
一道很’裸’的BFS模板题,完全没有变动的地方,用到的数据结构有STL中的queue,以及一个二维数组vis[][]用来进行最初的存图以及之后标记是否走过。
在寻找路径方面,我没有用map存储每一个点的前驱节点,而是从终点又反向BFS了一遍来找出路径,(利用条件 vis[u.x][u.y]==vis[now.x][now.y]-1来找出)将每一个找到的路径上的点push_back进vector,然后搜到起点时停下,并反向遍历vector。(PS:主要是不习惯用map,写完之后才发现用map记录路径似乎可以使代码更简洁 orz)
总结
1.BFS模板:利用queue 别忘了判断终点到达条件 有无越界 是否可以走
2.寻找路径:可以用map建立点到点的映射 并且递归或者用vector来实现路径的输出
代码
#include<iostream>
#include<queue>
#include<math.h>
#include<algorithm>
#include<stdio.h>
#include<vector>
using namespace std;
int vis[11][11];
const int dx[]={0,0,1,-1};
const int dy[]={1,-1,0,0};
struct point
{
int x;int y;
};
void bfs()
{
queue<point> q;
vis[0][0]=0;
q.push({0,0});
while(!q.empty())
{
point now=q.front();q.pop();
if(now.x==4&&now.y==4) return ;
for(int i=0;i<4;i++)
{
point u;
u.x=now.x+dx[i];u.y=now.y+dy[i];
if(u.x>=0&&u.x<=4&&u.y>=0&&u.y<=4&& vis[u.x][u.y]==-1)
{
vis[u.x][u.y]=vis[now.x][now.y]+1;
q.push(u);
}
}
}
}
void print()
{
vector<point> v;
queue<point> q;
q.push({4,4});
v.push_back({4,4});
while(!q.empty())
{
point now=q.front();q.pop();
if(now.x==0&&now.y==0) break ;//反向搜一遍来确定路径
for(int i=0;i<4;i++)
{
point u;
u.x=now.x+dx[i];u.y=now.y+dy[i];
if(u.x>=0&&u.x<=4&&u.y>=0&&u.y<=4&& vis[u.x][u.y]==vis[now.x][now.y]-1)
{
v.push_back(u);
q.push(u);
}
}
}
for(int i=v.size()-1;i>=0;i--)
cout<<"("<<v[i].x<<", "<<v[i].y<<")"<<endl;
}
int main()
{
int x;
for(int i=0;i<5;i++)
for(int j=0;j<5;j++)
{
cin>>x;
x==0?vis[i][j]=-1:vis[i][j]=-2;//用-2表示用障碍物 用-1表示未到达过但可到达
}
bfs();
print();
system("pause");
return 0;
}