迷宫问题的最短路,加最小字典序
迷宫文件maze.txt传送门
作者写的2019年B组蓝桥杯解集
.
.
.
DFS的版本
#include<iostream>
#include<cstring>
using namespace std;
const int ax[4]={0,0,1,-1};
const int ay[4]={1,-1,0,0};
const char dir[5]={'R','L','D','U'};
int maze[60][60],mins[60][60];
char a[2000];
int best;
string ans;
bool judge(int x,int y) {//判断这个点是否越界,是否走过。
if(x>0&&x<=30&&y>0&&y<=50&&!maze[x][y])
return true;
return false;
}
void dfs(int x,int y,int pos) {
if(pos>best)
return ;
if(x==30&&y==50) {
string temp;
for(int i=1;i<pos;i++)
temp+=a[i];
if(pos<best) {//是最短的路
ans=temp;
best=pos;
}
else if(pos==best&&temp<ans) ans=temp;//在实现路时最短的同时,保证字典序最小。
return ;
}
for(int i=0;i<4;i++) {
int tempx=x+ax[i];
int tempy=y+ay[i];
if(judge(tempx,tempy)&&pos+1<=mins[tempx][tempy]) {
maze[tempx][tempy]=1;
mins[tempx][tempy]=pos+1;
a[pos]=dir[i];
dfs(tempx,tempy,pos+1);
maze[tempx][tempy]=0;//回溯找短的路,或者时字典序最小的。
}
}
}
int main()
{
freopen("D:\MY\ce.txt","r",stdin);
memset(mins,1,sizeof(mins));
best=1<<28;
for(int i=1;i<=30;i++)
for(int j=1;j<=50;j++) {
char t;
cin>>t;
maze[i][j]=t-'0';
}
maze[1][1]=1;
dfs(1,1,1);
cout<<ans<<endl;
return 0;
}
其中最重要的就是数组mins,这里记录了从起始位置到这里的最短步数,
l
l当这个点在可以到达终点的路径上时,也有可能有多种方式到这个点,所以一点更要保证时最小的步数到可以到达终点的路径上的点。
.
.
.
BFS版本
#include<iostream>
#include<cstring>
#include<queue>
const int ax[4]={1,0,0,-1};
const int ay[4]={0,-1,1,0};
const char dir[5]={'D','L','R','U'};
int maze[40][60];
using namespace std;
struct point {
int x,y;
string ans;
point(int a,int b,string c):x(a),y(b),ans(c){}
};
bool judge(int x,int y) {
if(x>0&&x<=30&&y>0&&y<=50&&!maze[x][y])
return true;
return false;
}
void bfs() {
queue<point>ans;
ans.push(point(1,1,""));
maze[1][1]=1;
while(!ans.empty()) {
point temp=ans.front();
ans.pop();
if(temp.x==30&&temp.y==50) {
cout<<temp.ans<<endl;
return ;
}
for(int i=0;i<4;i++) {
int tempx=temp.x+ax[i];
int tempy=temp.y+ay[i];
if(judge(tempx,tempy)) {
maze[tempx][tempy]=1;
ans.push(point(tempx,tempy,temp.ans+dir[i]));
}
}
}
}
int main() {
freopen("D:\MY\ce.txt","r",stdin);
for(int i=1;i<=30;i++)
for(int j=1;j<=50;j++) {
char t;
cin>>t;
maze[i][j]=t-'0';
}
bfs();
return 0;
}
这里就不用考虑回溯的问题,不用考虑是不是最短路的问题,但是可能有一个是不是字典序最小需要考虑,
.
于是我把这里的dir方向数组设置成了"D L R U"的顺序,保证了在步数最小的前提下最小字典序一定会最早出现。
DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR
*
**
**
*
还有一点要注意的就是,我这里 用的是int数组存地图,地图之间没有空格,一定要先用char读取,或者直接用char数组表示地图。
.
就因为这个,我抑郁了好久,一直不知道哪里错了。