kuangbin搜索专题 B - Dungeon Master(POJ - 2251)(BFS)

BFS(宽度优先搜索):

应用队列(先进先出)   达到一层一层遍历的效果

比如说第一步6个状态皆可走,则向对列中存入6个元素,之后再循环依次拿出6个状态,

每个状态的情况都存入在这第一次的6个状态之后,然后依次往后放,以此来达到一层一层的操作;

strchr()和strrchr():

要在<cstring>头文件中

strchr(char *str, int c)

str是字符串,c是要查找的字符,从左开始查找,如果找到输出最先出现的位置,否则输出NULL;

strrchr(char *str, int c)

strrchr是从右开始查找,即最后出现的位置;

Dungeon Master:

题目大意:(文末有原题)

给你一个立体迷宫,只能上、下、左、右、上楼梯、下楼梯(不能斜着走);问能否走出迷宫,输出最短时间或“Trapped!”;

思路:

迷宫问题,要求最短时间,即求最短路径,bfs;

代码:

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
//bfs宽搜; 
const int maxn = 30 + 5;

int l, r, c, ans;		//输入的层,行,列,ans 用于记录答案 
int sl, sr, sc, el, er, ec;		//s~起始	e~结束 
char mmap[maxn][maxn][maxn];		//地图,存放每个元素的状态 
int vis[maxn][maxn][maxn];		//记录是否走过该点 

const int dz[] = {0, 0, 0, 0, 1, -1};	//六个方向: 
const int dx[] = {-1, 0, 1, 0, 0, 0};	//上 下 左 右 下一层 上一层 
const int dy[] = {0, 1, 0, -1, 0, 0};	 

struct Node{				//记录节点,并且记录步数; 
	int l, r, c, step;
	Node(int l = 0, int r = 0, int c = 0, int step = 0) : r(r), l(l), c(c), step(step) {} 
};

int check(int x, int y, int z) {		//检查是否允许进行这一步 
	if(x < 0 || y < 0 || z < 0 || x >= l || y >= r || z >= c)	//先判断是否出界 
		return 1;
	else if(mmap[x][y][z] == '#') 		//判断是否是不可走的地方 
		return 1;
	else if(vis[x][y][z])		//判断是否已经走过 
		return 1;
	return 0;
} 

int bfs() {			 
	queue<Node> n;
	n.push(Node(sl, sr, sc, 0));	//初始状态入队 
	vis[sl][sr][sc] = 1;			//标记为已走 

	while(!n.empty() ) {			//判断是否为空,如果为空 表示上一步无论如何走都不会有允许的下一步, 
		Node now = n.front();					//即无结果 
		n.pop();
		if(now.l == el && now.r == er && now.c == ec) {
			ans = now.step;			//记录答案 
			return 1;
		}
		
		int ll, rr, cc, st;		//此状态时的l,r,c,step; 
		
		for(int i = 0; i < 6; i++) {	//6个方向移动 
			ll = now.l + dz[i];
			rr = now.r + dx[i];
			cc = now.c + dy[i];
			st = now.step + 1;
			if(check(ll, rr, cc))
				continue;
			vis[ll][rr][cc] = 1;		
			n.push(Node(ll, rr, cc, st));	//若满足则存入 
		}				
	}
						
	return 0;
}

int main() {
	while(scanf("%d%d%d", &l, &r, &c) && (l != 0 && r != 0 && c != 0)){
		for(int i = 0; i < l; i++)
			for(int j = 0; j < r; j++) {
				cin >> mmap[i][j];
				if(strchr(mmap[i][j], 'S'))
					sl = i, sr = j, sc = strchr(mmap[i][j], 'S') - mmap[i][j];
				if(strchr(mmap[i][j], 'E'))
					el = i, er = j, ec = strchr(mmap[i][j], 'E') - mmap[i][j];
			}
		
		memset(vis, 0, sizeof(vis));
		if(bfs()) cout << "Escaped in " << ans << " minute(s).\n";
		else cout << "Trapped!\n";
	
	}
	
	return 0;
}

题目:
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?

输入:

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.

输出:

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!

样例:

Input:                        Output:

3 4 5

S....

.###.

.##..

###.#

 

#####

#####

##.##

##...

 

#####

##### 

#.### 

####E  ---------------------- Escaped in 11 minute(s).

 

1 3 3

S##

#E#

### --------------------------- Trapped!

 

0 0 0

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值