迷宫问题的最短路,加最小字典序
迷宫文件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数组表示地图。
.
就因为这个,我抑郁了好久,一直不知道哪里错了。