1248:Dungeon Master
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 1730 通过数: 702
【题目描述】
这题是一个三维的迷宫题目,其中用‘.’表示空地,‘#’表示障碍物,‘S’表示起点,‘E’表示终点,求从起点到终点的最小移动次数,解法和二维的类似,只是在行动时除了东南西北移动外还多了上下。可以上下左右前后移动,每次都只能移到相邻的空位,每次需要花费一分钟,求从起点到终点最少要多久。
【输入】
多组测试数据。
一组测试测试数据表示一个三维迷宫:
前三个数,分别表示层数、一个面的长和宽,后面是每层的平面图。前三个数据为三个零表示结束。
【输出】
最小移动次数。
【输入样例】
3 4 5
S…
.###.
.##…
###.#
##.##
##…
#.###
####E
1 3 3
S##
#E#
0 0 0
【输出样例】
Escaped in 11 minute(s).
Trapped!
【提示】
对于题目给出数据的含义就是输入l,r,c,分别代表迷宫有l层,每层长宽分别是c,r。对于数据以可以这样移动:
(1,1,1)->(1,1,2)->(1,1,3)->(1,1,4)->(1,1,5)->(1,2,5)->
(1,3,5)->(1,3,4)->(1,4,4)->(2,4,4)->(2,4,5)->(3,4,5)
共11步就可以到达终点 对于数据二明显不能到达,则输出Trapped!
这题用BFS解,每次去队首元素,如果是终点则输出结果移动的次数,否则,从该点开始分别向东南西北上下移动(如果可以走的话)并继续搜,如果到队列为空还没搜到解法,则说明无解。
#include<iostream>
#include<cstring>
using namespace std;
bool a[31][31][31],v[31][31][31];
int qi[100001],qj[100001],qk[100001],qans[100001];
int dis[6][3]={{1,0,0},{0,1,0},{0,0,1},{-1,0,0},{0,-1,0},{0,0,-1}};
int main()
{
int y1,x1,z1,si,sj,sk,ei,ej,ek;
while(cin>>x1>>y1>>z1&&x1&&y1&&z1)
{
memset(a,false,sizeof(a));
memset(v,false,sizeof(v));
for(int i=1;i<=x1;i++)
for(int j=1;j<=y1;j++)
for(int k=1;k<=z1;k++)
{
char c;
cin>>c;
if(c=='.')
a[i][j][k]=true;
if(c=='S')
{
si=i;
sj=j;
sk=k;
a[i][j][k]=true;
}
if(c=='E')
{
ei=i;
ej=j;
ek=k;
a[i][j][k]=true;
}
}
int head=0,tail=1;
bool ok=false;
qi[0]=si;
qj[0]=sj;
qk[0]=sk;
v[si][sj][sk]=true;
while(head!=tail)
{
int x=qi[head];
int y=qj[head];
int z=qk[head];
int ans=qans[head];
if(x==ei&&y==ej&&z==ek)
{
cout<<"Escaped in "<<ans<<" minute(s)."<<endl;
ok=true;
break;
}
head++;
for(int i=0;i<6;i++)
{
int nx=x+dis[i][0];
int ny=y+dis[i][1];
int nz=z+dis[i][2];
if(a[nx][ny][nz]&&nx<=x1&&ny<=y1&&nz<=z1&&nx&&ny&&nz&&!v[nx][ny][nz])
{
v[nx][ny][nz]=true;
qi[tail]=nx;
qj[tail]=ny;
qk[tail]=nz;
qans[tail]=ans+1;
tail++;
}
}
}
if(!ok)
cout<<"Trapped!"<<endl;
}
return 0;
}