poj2251 dungeon master【BFS】~

来源:互联网 发布:焊接分析软件 编辑:程序博客网 时间:2024/04/29 05:15

Dungeon Master

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/65536K (Java/Other)
Total Submission(s) : 60   Accepted Submission(s) : 26
Problem 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!
 

Sample Input
3 4 5S.....###..##..###.#############.####...###########.#######E1 3 3S###E####0 0 0
 

Sample Output
Escaped in 11 minute(s).Trapped!
 
【考察点】:BFS模板变形
【题目大意】:有一个三维的地牢,S是起点,E是终点,每次可以向前、后、左、右、上、下六个方向挪动,每挪动一步需要一分钟。
输入:输入包括多组测试数据,每组测试数据第一行有三个整数L,R,C,L是这个地牢的层数,R和C分别代表每层的行数和列数,接下来有L块R行C列的字符,每一个字符代表地牢的一个单元格。'#'表示石头,'.'是空的可以通过,起始位置是'S',出口是'.'。
输出:如果能到达出口,输出所用最短时间"Escaped in x minute(s)."否则输出"Trapped!"
【解题思路】:只需要把BFS模板中的dx[4]={0,0,1,-1},dy[4]={1,-1,0,0}变为dx[6]={0,0,0,0,-1,1},dy[6]={0,0,-1,1,0,0},dz[6]={-1,1,0,0,0,0}就能实现向前后左右上下六个方向移动了。
 
【代码】
#include<stdio.h>#include<string.h>#include<queue>#include<iostream>using namespace std;#define INF 0xfffffffint x,y,z,ex,ey,ez,ans,vis[35][35][35],L,R,C,flag;//定义dis数组用来标记int dx[6]={0,0,0,0,-1,1};int dy[6]={0,0,-1,1,0,0};int dz[6]={-1,1,0,0,0,0};//定义数组实现前后左右上下六个方向的移动char map[35][35][35];//注意定义三维数组struct node{int x,y,z,step;friend bool operator < (node a,node b){return a.step>b.step;//结构体中,step小的优先级高}}a,temp;int jud(struct node a)//用jud函数对各种情况进行判断,跳过不合要求的,即不能走的{if(a.x<0||a.x>=R)    return 0;if(a.y<0||a.y>=C)    return 0;if(a.z<0||a.z>=L)    return 0;if(vis[a.x][a.y][a.z]||map[a.x][a.y][a.z]=='#')    return 0;if(temp.step>=ans)    return 0;return 1;}void bfs(){flag=0;a.x=x;a.y=y;a.z=z;a.step=0;memset(vis,0,sizeof(vis));//将vis数组初始化为0priority_queue<node>q;vis[x][y][z]=1;遍历过的点vis为1q.push(a);while(!q.empty()){a=q.top();q.pop();for(int i=0;i<6;i++)//向前后左右上下中的一个方向挪动一步{temp.x=a.x+dx[i];temp.y=a.y+dy[i];temp.z=a.z+dz[i];temp.step=a.step+1;//步数加1if(jud(temp)){if(temp.x==ex&&temp.y==ey&&temp.z==ez)//如果到达终点{ans=temp.step;flag=1;//能到终点,用flag标记一下return;}vis[temp.x][temp.y][temp.z]=1;q.push(temp);}}}}int main(){int i,j,k;while(scanf("%d%d%d",&L,&R,&C)&&(L||R||C)){for(k=0;k<L;k++){for(i=0;i<R;i++)              for(j=0;j<C;j++)       {           cin>>map[i][j][k];//注意输入的方法,由于用printf输入要考虑多处吸收空格,所以用这种方法输入比较简便           if(map[i][j][k]=='S')              x=i,y=j,z=k;          if(map[i][j][k]=='E')              ex=i,ey=j,ez=k;   }}if(x==ex&&y==ey&&z==ez){printf("Escaped in 0 minute(s).\n");continue;}ans=INF;bfs();if(flag)   printf("Escaped in %d minute(s).\n",ans);else   printf("Trapped!\n");}return 0;}

0 0