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. clone分支,修改文件本地commit后, push回原分支失败,处理方法

    从远程clone 一个仓库到本地仓库A后,由于有多个分支,经常需要切换,不同分支区别比较大,切换一下,需要重编译,于是又在本地clone了改动较大的一个分支F到仓库B: 在B仓库改动后,提交到A仓库的 ...

  2. 剑指Offer的学习笔记(C#篇)-- 从上往下打印二叉树

    题目描述 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 一 . 题目解析 了解过二叉树就应该知道,二叉树存在三种遍历方法:前序遍历(根→左→右).中序遍历(左→根→右).后续遍历(左→右→根 ...

  3. GridSearchCV.grid_scores_和mean_validation_score报错

    目录 GridSearchCV.grid_scores_和mean_validation_score报错 0. 写在前面 1. 问题描述和解决过程 2. 不想比比直接看结果部分 GridSearchC ...

  4. 安装mongo可视化管理工具mongo admin

    https://github.com/mrvautin/adminMongo github地址 安装要求下载下来,然后安装即可 中间出现了问题: 说是开了代理,可以关掉代理之后,然后把下载下来的删了, ...

  5. jQuery EasyUI/TopJUI上传多个附件并可以进行删除操作

    jQuery EasyUI/TopJUI上传多个附件并可以进行删除操作 html <table data-toggle="topjui-datagrid" data-opti ...

  6. LDAP第三天 MySQL+LDAP 安装

    https://www.easysoft.com/applications/openldap/back-sql-odbc.html      OpenLDAP 使用 SQLServer 和 Oracl ...

  7. javascript中的style只能取到在HTML中定义的css属性

    如果在css中定义的 li{ width:100px; left:100px; top:; position:absolute; font-style:normal; } 这样执行: oli[0].s ...

  8. Django - CRM项目(3)

    一.CRM项目的业务逻辑与表结构梳理 1.分析业务逻辑 (1) 引流(sem) (2) 网络咨询师(客服):添加客户信息和查看客户,分配销售 (3) 销售:查看私户 添加跟进记录 失败:加入公户 成功 ...

  9. 【OGG】OGG的单向DML复制配置(一)

    [OGG]OGG的单向DML复制配置(一) 一.1  BLOG文档结构图 一.2  前言部分 一.2.1  导读 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识, ...

  10. 关于AQS——独占锁的相关方法(一)

    一.序言 Lock接口是juc包下一个非常好用的锁,其方便和强大的功能让他成为synchronized的一个很好的替代品. 我们常用的一个Lock的实现类(好像也是唯一一个只实现了Lock接口的类) ...