Dungeon Master——poj2251(广搜)(超详细)

Dungeon Master
时间限制: 1000MS 内存限制: 65536K
提交总数: 61562 接受: 22565
Descriptions:
你被困在一个3D地牢中且继续寻找最短路径逃生!地牢由立方体单位构成,立方体单位中有的会充满岩石。向上下前后左右移动一个单位需要一分钟。你不能向对角线的四个方向移动且迷宫四周环绕着许多岩石。
是否可以逃出地牢?如果可以,则需要多少时间?
Input:
输入的第一行包含一个数,表示地牢的数量。
每个地牢的描述,其第一行包含三个数L,R和C(均小于等于30)。
L表示地牢的层数;R和C分别表示每层地牢的行与列的大小。
随后输入地牢的层数L,每层中包含R行,每行中包含C个字符。
每个字符表示地牢的一个单元。’#‘表示岩石单元,’.‘表示空白单元。你的起始位置在点’S’,出口为’E’。
每层地牢的输入后都有一个空行。当L,R和C均为0时,输入结束。
Output:
每个迷宫对应一行输出。
如果可以逃生,则输出如下
Escaped in x minute(s).
x为最短脱离时间。
如果无法逃生,则输出如下
Trapped!

Sample Input
3 4 5
S…
.###.
.##…
###.#

##.##
##…

#.###
####E

1 3 3
S##
#E#

0 0 0
Sample Output:
Escaped in 11 minute(s).

Trapped!

题意思路:3维的迷宫问题,问是否存在路线,而不是多少种方法,考虑用广搜。
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
int l,r,c;
char mp[35][35][35];//存储迷宫
int vis[35][35][35];//标记是否走过
int sx,sy,sz,ex,ey,ez;//开始和结尾的位置
int dx[6]={1,-1,0,0,0,0},dy[6]={0,0,1,-1,0,0},dz[6]={0,0,0,0,1,-1};//6个方向走
struct Mp
{
    int x,y,z;
}m;
int bfs()
{
    queue<Mp>q;
    for(int i=0;i<l;i++)
    {
        for(int j=0;j<r;j++)
        {
            for(int k=0;k<c;k++)
            {
                vis[i][j][k]=INF;//初始化为无穷
            }
        }
    }
    vis[sx][sy][sz]=0;//用来累计用了多少单位时间,开始位置初始化为0
    m.x=sx,m.y=sy,m.z=sz;
    q.push(m);// 将m(开始位置的坐标)压入队列尾部(入队)(队列只能在队尾插入元素,在队首删除元素)
    while(q.size()!=0)//返回队列中元素的个数(队列不为空一直执行,直到队列为空)
    {
        Mp temp=q.front();//返回队首元素,但不删除(队首元素赋值给temp)
        q.pop();//删除队首元素但不返回(出队)
        if(temp.x==ex&&temp.y==ey&&temp.z==ez)break;
        for(int i=0;i<6;i++)//6种走法
        {
            int nx=temp.x+dx[i],ny=temp.y+dy[i],nz=temp.z+dz[i];
            if((nx>=0&&nx<l)&&(ny>=0&&ny<r)&&(nz>=0&&nz<c)&&vis[nx][ny][nz]==INF&&mp[nx][ny][nz]!='#')//判断是否能走
            {
                Mp ans;
                ans.x=nx,ans.y=ny,ans.z=nz;
                q.push(ans);//将ans压入队列尾部
                vis[nx][ny][nz]=vis[temp.x][temp.y][temp.z]+1;
            }
        }
    }
    return vis[ex][ey][ez];
}

int main()
{
    while(cin>>l>>r>>c&&l!=0&&r!=0&&c!=0)
    {
        for(int i=0;i<l;i++)
        {
            for(int j=0;j<r;j++)
            {
                for(int k=0;k<c;k++)
                {
                    cin>>mp[i][j][k];
                    if(mp[i][j][k]=='S')
                        sx=i,sy=j,sz=k;
                    if(mp[i][j][k]=='E')
                        ex=i,ey=j,ez=k;
                }
            }
            getchar();//读入一个字符判断是否回车,不是就继续读,是回车就退出循环(整个地图读入后以回车结束)
        }
        int num=bfs();
        if (num!= INF)
            cout<<"Escaped in "<<num<<" minute(s)."<<endl;
        else
            cout<<"Trapped!"<<endl;
    }
    return 0;
}


感悟:因为是看着别人代码敲的,理解不深,有时间会更新这篇博客的。。。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值