题目大意是,给你一个二维数组,5*5的,这个图中有墙,现在让你找出从左上角到右下角的最短路径,并把路径输出;
分析,其实这道题的难点只有一个,就是如何把最短路径按顺序输出,找到最短路径其实只需要bfs就好
我的做法是,使用一个逆向的方向数组,和一个栈
比如bfs的方向数组是{1,0},{-1,0},{0,1},{0,-1} 那么逆向数组依次就是{-1,0},{1,0},{0,-1},{0,1}这样就可以通过最后一个点来复原他的上一个状态,最后让你通过逆向数组得到的坐标跟栈中存放的坐标进行比较,如果相同那么栈中的那个点就是这个点的上一个状态
代码
#include<iostream>
#include<stack>
#include<queue>
#include<cstdio>
using namespace std;
int vis[5][5];
int mp[5][5];
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
int fdir[4][2]={{-1,0},{1,0},{0,1},{0,-1}};//逆向数组
int n;
struct summer
{
int x,y;
int i;//记录这个点是经过那种变化得到的,方便回来使用逆向数组来复原
int step;
friend bool operator < (summer a,summer b)
{
return a.step>b.step;
}
};
vector<summer>oj;
stack<summer>iron;
void line(summer a)//通过这个函数,来得到每一个点的上一个状态
{
summer b;
a.x+=fdir[a.i][0];//逆向过程
a.y+=fdir[a.i][1];
while(!iron.empty())
{
b=iron.top();
iron.pop();
if(b.x==a.x&&b.y==a.y)//判断经过你逆向复原的坐标在不在栈中,栈存放的是bfs时经过的所有坐标;
{
a.x=b.x;
a.y=b.y;
a.i=b.i;
a.x+=fdir[a.i][0];
a.y+=fdir[a.i][1];
oj.push_back(b);//如果相同,压入vector中,以便输出路线;
}
}
for(int i=oj.size()-1;i>=0;i--)
{
printf("(%d, %d)\n",oj[i].x,oj[i].y);
}
printf("(4, 4)\n");//不要忘了4,4这个坐标,因为这个点并没有被压入栈中
}
void bfs()
{
priority_queue<summer>que;
summer a,a2;
a.x=0;
a.y=0;
a.i=0;
a.step=0;
vis[0][0]=1;
que.push(a);
while(!que.empty())
{
a=que.top();
iron.push(a);//这个就是把bfs的所有路线上的点全部压入栈中,为了后面与复原坐标比较得出正确的坐标
que.pop();
if(a.x==4&&a.y==4)
{
line(a);
break;
}
for(int i=0;i<4;i++)
{
a2.x=a.x+dir[i][0];
a2.y=a.y+dir[i][1];
a2.i=i;
if(a2.x<0||a2.y<0||a2.x>=5||a2.y>=5||vis[a2.x][a2.y]==1) continue;
if(mp[a2.x][a2.y]!=1)
{
a2.step++;
vis[a2.x][a2.y]=1;
que.push(a2);
}
}
}
}
int main()
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
scanf("%d",&mp[i][j]);
}
}
bfs();
return 0;
}