概述
【问题描述】
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可
以通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这
个它的上、下、左、右四个方向之一。
对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,
一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。
对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式,
其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。
请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务
必检查复制的内容是否与文档中的一致。在试题目录下有一个文件 maze.txt,
内容与下面的文本相同)
因为寒假刚好自己学了dfs和bfs,刷题的时候看到,还算是比较典型的题型吧。
//E 迷宫-已完成
#include<iostream>
#include<string>
#include<queue>
using namespace std;
int n,m;
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};//四个方向
char d[4]={'U','L','D','R'};//四个方向所要对应的字母
struct node//每一个状态点
{
int x;int y;//x,y值以及输出时用到的字符串
string s;
};
bool in(int x,int y){//判断点在边界内
return x>0&&x<=n&&y>0&&y<=m;
}
char map[55][55];//地图,开大一点无所谓
bool vis[55][55];
void bfs(int x,int y)
{
queue<node >q;
node cur,nex;//初始化,也可以用构造函数写,但是比较懒
//cur当前点 ,nex下一状态点
cur.x=x;
cur.y=y;
cur.s="";
q.push(cur);
while(!q.empty())
{
cur=q.front();
q.pop();
for(int i=0;i<4;i++){
nex.x=cur.x+dir[i][0];
nex.y=cur.y+dir[i][1];
if(in(nex.x,nex.y)&&map[nex.x][nex.y]!='1'&&!vis[nex.x][nex.y]){//如果下一个点符合条件,那么判断他是否为终点
nex.s=cur.s+d[i];//追加方向字母
vis[nex.x][nex.y]=true;//走过的点不重复走
if(nex.x==n&&nex.y==m){//如果是终点,就输出当前状态的字符串
cout<<nex.s<<endl;
return;
}
q.push(nex);//塞入队列
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>map[i][j];
}
}
vis[1][1]=true;//走过的点不重复走
bfs(1,1);//
}