Dungeon Master的两种方法
Is an escape possible? If yes, how long will it take?
Input
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
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的两种方法的更多相关文章
- hive权威安装出现的不解错误!(完美解决)两种方法都可以
以下两种方法都可以,推荐用方法一! 方法一: 步骤一: yum -y install mysql-server 步骤二:service mysqld start 步骤三:mysql -u root - ...
- 两种方法上传本地文件到github
https://www.jianshu.com/p/c70ca3a02087 自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的 ...
- 两种方法上传本地文件到github(转)
自从使用github以来,一直都是在github网站在线上传文件到仓库中,但是有时因为网络或者电脑的原因上传失败.最重要的原因是我习惯本地编辑,完成以后再一起上传github.看过了几个教程,总结出最 ...
- 在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法。
在vc6.0下编的对话框界面如果没做过其他处理,往往显的很生硬,怎么样才能使他有Windows XP的风格呢,其实也很简单,我们来看看下面两种方法. 方法一: 1.首先确认你在Windows ...
- [整理] C#调用SQLDMO.DLL时间数据库备份 / 还原。 (香神无涯) // C#实现SQLSERVER2000数据库备份还原的两种方法 (带进度条)
/// <summary>/// 通过调用MSSQL的SQLDMO.DLL文件来实现备份数据库/// 1.首先在在项目中引用SQLDMO.DLL文件./// 2.在引用中的SQLDMO.D ...
- GitHub常用上传文件的两种方法 附带常见的问题及Git安装教程
从早上下课到现在一直在琢磨如何给Github下载本地文件,中午饭都没吃.还好是解决了,感觉挺有成就感的.O(∩_∩)O哈哈~ 好哒 闲话不说,说重点. 一.git的安装 百度云:http://pan. ...
- Git恢复之前版本的两种方法reset、revert
实战 回退 1.删除之前的提交 git reset --hard id 推送到远程 git push -f [git log中确实删除了,但是拿到可以恢复] 2.不删除之前的提交 git revert ...
- windows下获取IP地址的两种方法
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- android 之 启动画面的两种方法
现在,当我们打开任意的一个app时,其中的大部分都会显示一个启动界面,展示本公司的logo和当前的版本,有的则直接把广告放到了上面.启动画面的可以分为两种设置方式:一种是两个Activity实现,和一 ...
随机推荐
- 数据库路由中间件MyCat - 使用篇(6)
此文已由作者张镐薪授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 配置MyCat 4. 配置schema.xml schema.xml里面管理着MyCat的逻辑库.表,每张表 ...
- 开源:基于Android的室内定位WiFi,iBeacon数据采集和定位脚本
最近有同学联系我,也在一些群里看到有新手同学挣扎在怎么获取定位数据,不知从何下手.所以整理并开源这个基于Android的数据采集软件和基于python的KNN定位demo,算是为新手同学建立一个Bas ...
- Intellij IDEA生成JavaDoc(转)
Intellij IDEA生成JavaDoc(转)
- Linux之vim基本命令操作
安装vim(yum -y install vim) 三种工作模式(命令模式.输入模式.编辑模式) 打开文件( vi ) 查找文本( / ) 替换文本 删除文本( dd 删除光标所在行 ) 复制文本 去 ...
- linux命令之ll按时间和大小排序显示
ll不是命令,是ls -l的别名 按大小排序 [root@localhost ~]# ll -Sh 按时间排序 [root@localhost ~]# ll -rt ll -t 是降序, ll -t ...
- Python绘制正态分布曲线
使用Python绘制正态分布曲线,借助matplotlib绘图工具: \[ f(x) = \dfrac{1}{\sqrt{2\pi}\sigma}\exp(-\dfrac{(x-\mu)^2}{2 ...
- codevs 3162 抄书问题
3162 抄书问题 题目描述 Description 现在要把M本有顺序的书分给K个人复制(抄写),每一个人的抄写速度都一样,一本书不允许给两个(或以上)的人抄写,分给每一个人的书,必须是连续的,比如 ...
- oracle merge 目标表以及源表存在重复列的问题(转)
SQL> select * from t_source; ...
- 界面切换动画(CATransition实现 )
调用 // CATransition动画实现 [self pushWithAnimationType:@"fade"]; - (void)pushWithAnimationType ...
- 什么是微服务架构,.netCore微服务选型
什么是微服务架构,.netCore微服务选型 https://www.cnblogs.com/uglyman/p/9182485.html 开发工具:VS2017 .Net Core 2.1 什么是微 ...