[題目鏈接] http://oj.ecustacm.cn/problem.php?id=1455
1455: [藍橋杯2019初賽]迷宮
題目描述
下圖給出了一個迷宮的平面圖,其中標記爲1 的爲障礙,標記爲0 的爲可
以通行的地方。
010000
000100
001001
110000
迷宮的入口爲左上角,出口爲右下角,在迷宮中,只能從一個位置走到這
個它的上、下、左、右四個方向之一。
對於上面的迷宮,從入口開始,可以按DRRURRDDDR 的順序通過迷宮,
一共10 步。其中D、U、L、R 分別表示向下、向上、向左、向右走。
對於下面這個更復雜的迷宮(30 行50 列),請找出一種通過迷宮的方式,
其使用的步數最少,在步數最少的前提下,請找出字典序最小的一個作爲答案。
請注意在字典序中D<L<R<U。
輸入
見文件:maze.txt
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <queue>
#include <stack>
using namespace std;
int m,n;
char Map[31][51];
int vis[30][50];
int dx[4]={1,0,0,-1};
int dy[4]={0,-1,1,0};
char dir[4]={'D','L','R','U'};
struct node
{
int x,y,step;
string str;
node node1(int xx,int yy,int step1,string s)
{
//構造函數不斷更新str
x=xx,y=yy,step=step1,str=s;
}
};
node pre[100][100];
int judge(int x,int y)
{
if(x>=0&&x<n&&y>=0&&y<m&&Map[x][y]=='0')
return 1;
return 0;
}
void bfs(node start)
{
queue<node>q;
node New,Now;
q.push(start);
vis[start.x][start.y]=0;
while(!q.empty())
{
Now=q.front();
q.pop();
if(Now.x==n-1&&Now.y==m-1)
{
printf("%d\n",Now.step);
cout<<Now.str<<endl;
return ;
}
for(int i=0;i<4;i++)
{
int nx=Now.x+dx[i],ny=Now.y+dy[i];
if(judge(nx,ny)&&!vis[nx][ny])
{
New.x=nx,New.y=ny,New.step=Now.step+1;
pre[nx][ny].x=Now.x;pre[nx][ny].y=Now.y;
New.str=Now.str+dir[i];//不斷更新字符
vis[nx][ny]=1;
q.push(New);
}
}
}
}
void print(node cur)
{
if(cur.x==0&&cur.y==0)
{
printf("(0,0)\n");
return ;
}
print(pre[cur.x][cur.y]);
printf("(%d,%d)\n",cur.x,cur.y);
}
int main()
{
int i,j;
scanf("%d%d",&n,&m);
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
cin>>Map[i][j];
}
node start;
start.x=0,start.y=0,start.step=0,start.str="";
bfs(start);
node ed;
ed.x=n-1,ed.y=m-1;
print(ed);
// cout<<"DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR"<<endl;
return 0;
}