题目链接:http://lx.lanqiao.cn/problem.page?gpid=T291
题意:走迷宫,左上角起点,右下角终点,只能走0,UDLR对应上下左右,找出最短路径及到最短路操作按字典序大小输出。
保存路径的时候用用一个多的结构体数组来存放下一个点的父亲节点和从当前点到下一个点需要的操作,然后再从终点不断的找父亲节点,直到找到起点,放入栈中,最后顺序出栈就是路径。
值得一提的是这里的最小字典序只要把我们需要改变的方向变成DLRU再保存即可。
#include<bits/stdc++.h>
using namespace std;
int dir[5][3]={{1,0},{0,-1},{0,1},{-1,0}},mp[510][510],vis[510][510];
char zm[]={'D','L','R','U'};
int n,m;
struct node{
int x,y,z;
};
struct FA{
int x,y;
char c;
};
FA pre[510][510];
void init(){
cin>>n>>m;
memset(mp,-1,sizeof mp);
for(int i=1;i<=n;i++){
string s;cin>>s;
for(int j=0;j<s.size();j++)
mp[i][j+1]=s[j]-'0';
}
}
bool check(int x,int y){
if(vis[x][y]==0 && mp[x][y]==0)
return true;
return false;
}
void bfs(int sx,int sy,int step){
queue<node> q;
int cnt=0;
q.push(node{sx,sy,0});
vis[sx][sy]=1;
while(!q.empty()){
node d=q.front();q.pop();
int x=d.x,y=d.y,z=d.z;
if(x==n && y==m){
cout<<z<<endl;
return;
}
for(int i=0;i<4;i++){
int nx=x+dir[i][0];
int ny=y+dir[i][1];
int nz=z+1;
if(check(nx,ny)){
vis[nx][ny]=1;
pre[nx][ny].x = x;//保存下个点的父亲点及操作方式
pre[nx][ny].y = y;
pre[nx][ny].c=zm[i];
q.push(node{nx,ny,nz});
}
}
}
}
void print(){
stack<char> lj;
while(!(pre[n][m].x==1&&pre[n][m].y==1)){
lj.push(pre[n][m].c);
int nn=pre[n][m].x;
int mm=pre[n][m].y;
n=nn;m=mm;
}
lj.push(pre[n][m].c);
while(!lj.empty()){
cout<<lj.top();
lj.pop();
}
}
int main(){
init();
bfs(1,1,0);
print();
return 0;
}