Description
You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides.

Is an escape possible? If yes, how long will it take?

Input

The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size).

L is the number of levels making up the dungeon.

R and C are the number of rows and columns making up the plan of each level.

Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a '#' and empty cells are represented by a '.'. Your starting position is indicated by 'S' and the exit by the letter 'E'. There's a single blank line after each level. Input is terminated by three zeroes for L, R and C.

Output

Each maze generates one line of output. If it is possible to reach the exit, print a line of the form

Escaped in x minute(s).

where x is replaced by the shortest time it takes to escape.

If it is not possible to escape, print the line

Trapped!

简单的说就是在三维地图中找最短路,具体题目请参见POJ2251

一、普通的bfs,配合优先队列

代码如下:

 #include<stdio.h>
#include<iostream>
#include<queue>
using namespace std;
char map[][][]; //记录节点信息
int sta[][][]; //标记是否访问
int base[][] = { {-,,},{,,},{,-,},{,,},{,,-},{,,} };
int L, R, C;
struct Piont
{
int x, y, z; //位置坐标
int step; //出发点到该点的步数
};
struct Piont s; //起点
struct Piont e; //终点
struct Piont curp; //跳出循环时的节点 /******************判断是否到达终点*********************/
bool success(struct Piont cur)
{
if (cur.x == e.x && cur.y == e.y && cur.z == e.z)
return true;
else
return false;
} /**************判断该点是否合法*************************/
bool check(int x, int y, int z)
{
if ((x >= ) && (x < L) && (y >= ) && (y < R) && (z >= ) && (z < C) && (!sta[x][y][z]) && (map[x][y][z] == '.' || map[x][y][z] == 'E'))
return true;
else
return false;
} /*************************深搜***************************/
void bfs()
{
struct Piont next;
queue<Piont>q;
q.push(s);
//int flag = 0;
while (!q.empty())
{
curp = q.front();
q.pop();
if (success(curp))
return;
else
{
sta[curp.x][curp.y][curp.z] = ;
for (int i = ; i < ; i++)
{
next.x = curp.x + base[i][];
next.y = curp.y + base[i][];
next.z = curp.z + base[i][];
if (check(next.x, next.y, next.z)) //扩展队列
{
next.step = curp.step + ;
sta[next.x][next.y][next.z] = ;
q.push(next);
}
}
}
}
}
int main()
{
while (scanf("%d%d%d", &L, &R, &C))
{
if((L == ) && (R == ) && (C == ))
break;
memset(sta, , sizeof(sta));
for (int i = ; i < L; i++) {
getchar();
for (int j = ; j < R; j++) {
for (int k = ; k < C; k++)
{
scanf("%c", &map[i][j][k]);
if (map[i][j][k] == 'S') {
s.x = i;
s.y = j;
s.z = k;
s.step = ;
}
else if (map[i][j][k] == 'E')
{
e.x = i;
e.y = j;
e.z = k;
}
}
getchar();
}
}
bfs();
if (curp.x == e.x && curp.y == e.y && curp.z == e.z)
printf("Escaped in %d minute(s).\n", curp.step);
else
printf("Trapped!\n");
}
return ;
}

二、递归(但由于多次重复经过某点,时间复杂度远大于方法一)

仅供参考,代码如下:

 #include<stdio.h>
#include<iostream>
using namespace std;
char map[][][];
int step_map[][][];
int sta[][][];
int s_x = -, s_y = -, s_z = -;
int e_x = -, e_y = -, e_z = -;
int step = , minn = << ;
int L, R, C;
int base[][] = { {-,,},{,,},{,-,},{,,},{,,-},{,,} }; bool check(int x, int y, int z)
{
if ((x >= ) && (x < L) && (y >= ) && (y < R) && (z >= ) && (z < C))
return true;
else
return false;
}
void bfs(int x, int y, int z)
{
int temp_x, temp_y, temp_z;
for (int i = ; i < ; i++)
{
if (x == e_x + base[i][] && y == e_y + base[i][] && z == e_z + base[i][])
{
if (step < minn)
minn = step;
return;
}
}
for (int i = ; i < ; i++)
{
temp_x = x + base[i][];
temp_y = y + base[i][];
temp_z = z + base[i][];
if ((!sta[temp_x][temp_y][temp_z]) && (map[temp_x][temp_y][temp_z] == '.') && (check(temp_x, temp_y, temp_z)))
{
step++;
if (step < step_map[temp_x][temp_y][temp_z]) //剪枝二:当前步数已大于曾经过该点的最小步数,停止搜索
{
step_map[temp_x][temp_y][temp_z] = step;
if (step < minn) //剪枝一:当前步数已大于或等于最小步数,停止搜索
{
sta[temp_x][temp_y][temp_z] = ;
bfs(temp_x, temp_y, temp_z);
sta[temp_x][temp_y][temp_z] = ;
}
}
step--;
}
}
}
int main()
{
while (scanf("%d%d%d",&L,&R,&C))
{
if ((L == ) && (R == ) && (C == ))
break;
memset(sta, , sizeof(sta));
//memset(step_map, (1 << 25), sizeof(step_map));//只能用来初始化为0、1和-1
for (int i = ; i < ; i++)
for (int j = ; j < ; j++)
for (int k = ; k < ; k++)
step_map[i][j][k] = ( << ); for (int i = ; i < L; i++) {
getchar();
for (int j = ; j < R; j++) {
for (int k = ; k < C; k++)
{
//cin >> map[i][j][k];
scanf("%c", &map[i][j][k]);
if (map[i][j][k] == 'S') {
s_x = i;
s_y = j;
s_z = k;
}
if (map[i][j][k] == 'E')
{
e_x = i;
e_y = j;
e_z = k;
}
}
getchar();
}
} bfs(s_x, s_y, s_z);
if (minn == ( << ))
printf("Trapped!");
else
{
printf("Escaped in %d minnute(s).", minn + );
minn = ( << );
step = ;
}
}
return ;
}

新手入门,希望大家多多指教!

Dungeon Master的两种方法的更多相关文章

  1. hive权威安装出现的不解错误!(完美解决)两种方法都可以

    以下两种方法都可以,推荐用方法一! 方法一: 步骤一: yum -y install mysql-server 步骤二:service mysqld start 步骤三:mysql -u root - ...

  2. 两种方法上传本地文件到github

    https://www.jianshu.com/p/c70ca3a02087 自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的 ...

  3. 两种方法上传本地文件到github(转)

    自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的原因是我习惯本地编辑,完成以后再一起上传github.看过了几个教程,总结出最 ...

  4. 在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法。

    在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法.    方法一: 1.首先确认你在Windows   ...

  5. [整理] C#调用SQLDMO.DLL时间数据库备份 / 还原。 (香神无涯) // C#实现SQLSERVER2000数据库备份还原的两种方法 (带进度条)

    /// <summary>/// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库/// 1.首先在在项目中引用SQLDMO.DLL文件./// 2.在引用中的SQLDMO.D ...

  6. GitHub常用上传文件的两种方法 附带常见的问题及Git安装教程

    从早上下课到现在一直在琢磨如何给Github下载本地文件,中午饭都没吃.还好是解决了,感觉挺有成就感的.O(∩_∩)O哈哈~ 好哒 闲话不说,说重点. 一.git的安装 百度云:http://pan. ...

  7. Git恢复之前版本的两种方法reset、revert

    实战 回退 1.删除之前的提交 git reset --hard id 推送到远程 git push -f [git log中确实删除了,但是拿到可以恢复] 2.不删除之前的提交 git revert ...

  8. windows下获取IP地址的两种方法

    windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...

  9. android 之 启动画面的两种方法

    现在,当我们打开任意的一个app时,其中的大部分都会显示一个启动界面,展示本公司的logo和当前的版本,有的则直接把广告放到了上面.启动画面的可以分为两种设置方式:一种是两个Activity实现,和一 ...

随机推荐

  1. VS~通过IIS网站启用"域名"调试

    在我们开发网站时,对某些信息进行序列化时,通常使用session,cookies,nosql等技术,而为了安全,我们在服务器上很多情况都做了防止盗链的设计,这给本机调试带来了不便,因为,本机都是以lo ...

  2. Kbengine

    Kbengine 编辑 KBEngine是一款开源的游戏服务端引擎,使用简单的约定协议就能够使客户端与服务端进行交互, 使用KBEngine插件能够快速与(Unity3D, OGRE, Cocos2d ...

  3. 洛谷 P1875 佳佳的魔法药水

    P1875 佳佳的魔法药水 题目描述 发完了 k 张照片,佳佳却得到了一个坏消息:他的 MM 得病了!佳佳和大家一样焦急 万分!治好 MM 的病只有一种办法,那就是传说中的 0 号药水 --怎么样才能 ...

  4. 阿里云服务器新手安装nginx

    1.域名购买之后 备案. 2.购买服务器. 3.这两个条件具备之后进行下一步. 本人使用Mac ,实践流程按照Mac本的流程操作. 作为初学者,简配的服务器, 实例类型: I/O优化,操作系统: Ce ...

  5. 理解JavaScript中的深拷贝和浅拷贝

    , num2 = num1;console.log(num1) //1console.log(num2) //1num2 = 2; //修改num2console.log(num1) //1conso ...

  6. 一个小时学会 MySQL 数据库

    随着移动互联网的结束与人工智能的到来大数据变成越来越重要,下一个成功者应该是拥有海量数据的,数据与数据库你应该知道. 一.数据库概要 数据库(Database)是存储与管理数据的软件系统,就像一个存入 ...

  7. phpstorm使用

    生成注释快捷键/**+enter 注释快捷键ctrl+/

  8. 4、CreateJS介绍-PreLoadJS

    需要在html5文件中引入的CreateJS库文件是preloadjs-0.4.1.min.js HTML5文件如下: <!DOCTYPE html> <html lang=&quo ...

  9. Web 加入favicon

    一.点击    制作自己的favicon图标; 二.在网页head中加入: <link rel="shortcut icon" href="favicon.ico& ...

  10. python进阶02 特殊方法与特殊属性

    python进阶02 特殊方法与特殊属性 一.初始化.析构 1.初始化 # python中有很多双下划线开头且以下划线结尾的固定方法,它们会在特定的时机被触发执行,这便是特殊方法 # 在实例化的时候就 ...