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. WSAData是个什么结构体用什么用

    WSAData机构体如下 功能是:存放windows socket初始化信息.struct WSAData { WORD wVersion; WORD wHighVersion; char szDes ...

  2. Django 之 requirement.txt 依赖文件生成

    通过依赖文件,别人在使用我们的项目时,不需要再一个个去安装所需模块,只需安装依赖文件即可. 1. 导出整个虚拟环境依赖 # 在项目根目录中,打开终端执行以下命令 # 生成 requirements.t ...

  3. JavaScript-导论

    说明:此类博客来自以下链接,对原内容做了标注重点知识,此处仅供自己学习参考! 来源:https://wangdoc.com/javascript/basic/introduction.html 1.什 ...

  4. cordova之旅之初识

    emmmm, 一直徘徊在移动端采用什么技术比较好,一直也没有找到,让我为了一个移动端而去学习一波react全家桶是不现实的操作,反观自己的技术栈,通过长时间的对比和剖析找到了入口点,不管了先会写再说吧 ...

  5. PHP之递归函数

    https://www.cnsecer.com/4146.html http://www.jb51.net/article/71424.htm //一列数字的规则如下:1,1,2,3,5,8,13,2 ...

  6. Awesome Blockchain 区块链技术导航

    区块链技术导航:收集整理最全面最优质的区块链(BlockChain)技术开发相关资源. 以后找不到文档资料的时候去导航站看看. 先亮个像,我长这样: 导航站内容 区块链开发所涉及的资源: 如 项目白皮 ...

  7. 笔记-JavaWeb学习之旅15

    Filter:过滤器 概念:当访问服务器的资源是,过滤器可以将请求拦截下来,完成一些特殊的功能 快速入门: 步骤: 定义一个类,实现接口Filter 复写方法 配置拦截路径 package com.d ...

  8. 分布式集群环境下,如何实现session共享一(应用场景)

    在web应用中,由于http的请求响应式,无状态.要记录用户相关的状态信息,比如电商网站的购物车,比如用户是否登录等,都需要使用session.我们知道session是由servlet容器创建和管理, ...

  9. jsonpath 求和

    { "price": [ 1.0, 2.0 ] } $..price.sum() 以下表达式

  10. python进阶09 MySQL高级查询

    python进阶09 MySQL高级查询 一.筛选条件 # 比较运算符 # 等于:= 不等于:!= 或<> 大于:> 小于:< 大于等于>= 小于等于:<= #空: ...