首页 > 其他 > 详细

POJ - 2251 Dungeon Master

时间:2020-06-15 09:04:31      阅读:42      评论:0      收藏: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?

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 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!


刚刚入门算法竞赛,做到此题,收获颇丰。
先放上本菜鸡第一次AC的代码:
  1 #include<iostream>
  2 #include<queue>
  3 #include<string.h>
  4 using namespace std;
  5 
  6 
  7 int maze[31][31][31]={0};
  8 struct pos{
  9     int x,y,z;
 10     pos(int x,int y,int z);
 11 };
 12 queue<pos> q;
 13 int time=0;
 14 int x,y,z,_x,_y,_z;
 15 pos::pos(int x,int y,int z){
 16     this->x=x;
 17     this->y=y;
 18     this->z=z;
 19 }
 20 void BFS(pos p0);
 21 
 22 int main(){
 23     
 24     cin >>z>>x>>y;
 25     while(z!=0||x!=0||y!=0){
 26         int begin_x,begin_y,begin_z;
 27         //建立3维棋盘
 28         for(int i=0;i<z;i++){
 29             for(int j=0;j<x;j++){
 30                 for(int k=0;k<y;k++){
 31                     char in;
 32                     cin >>in;
 33                     if(in==S){
 34                         maze[j][k][i]=0;
 35                         begin_x=j;begin_y=k;begin_z=i;
 36                     }else if(in==E){
 37                         maze[j][k][i]=0;
 38                         _x=j;_y=k;_z=i;
 39                     }else if(in==#){
 40                         maze[j][k][i]=-10;
 41                     }else if(in==.){
 42                         maze[j][k][i]=0;
 43                     }
 44                 }
 45             }
 46         }
 47         pos p0(begin_x,begin_y,begin_z);
 48         BFS(p0);
 49         memset(maze,0,sizeof(maze));
 50         time=0;
 51         while(!q.empty()){
 52             q.pop();
 53         }
 54         cin >>z>>x>>y;
 55     }
 56     system("pause");
 57     return 0;
 58 
 59 }
 60 
 61 void BFS(pos p0){
 62     maze[p0.x][p0.y][p0.z]=0;
 63     q.push(p0);
 64     bool OK=false;
 65     while(!q.empty()){
 66         pos u=q.front();
 67         q.pop();
 68         pos left(u.x,u.y-1,u.z),right(u.x,u.y+1,u.z);
 69         pos forward(u.x-1,u.y,u.z),back(u.x+1,u.y,u.z);
 70         pos up(u.x,u.y,u.z+1),down(u.x,u.y,u.z-1);
 71         if(left.y>=0&&maze[left.x][left.y][left.z]==0){
 72             maze[left.x][left.y][left.z]=maze[u.x][u.y][u.z]+1;
 73             if(left.x==_x&&left.y==_y&&_z==left.z){
 74                 OK=true;
 75                 time=maze[left.x][left.y][left.z];
 76                 break;
 77             }
 78             q.push(left);
 79         }
 80         if(right.y<=y-1&&maze[right.x][right.y][right.z]==0){
 81             
 82             maze[right.x][right.y][right.z]=maze[u.x][u.y][u.z]+1;
 83             if(right.x==_x&&right.y==_y&&_z==right.z){
 84                 OK=true;
 85                 time=maze[right.x][right.y][right.z];
 86                 break;
 87             }
 88             q.push(right);
 89         }
 90         if(forward.x>=0&&maze[forward.x][forward.y][forward.z]==0){
 91             
 92             maze[forward.x][forward.y][forward.z]=maze[u.x][u.y][u.z]+1;
 93             if(forward.x==_x&&forward.y==_y&&_z==forward.z){
 94                 OK=true;
 95                 time=maze[forward.x][forward.y][forward.z];
 96                 break;
 97             }
 98             q.push(forward);
 99         }
100         if(back.x<=x-1&&maze[back.x][back.y][back.z]==0){
101             
102             maze[back.x][back.y][back.z]=maze[u.x][u.y][u.z]+1;
103             if(back.x==_x&&back.y==_y&&_z==back.z){
104                 OK=true;
105                 time=maze[back.x][back.y][back.z];
106                 break;
107             }
108             q.push(back);
109         }
110         if(up.z<=z-1&&maze[up.x][up.y][up.z]==0){
111             
112             maze[up.x][up.y][up.z]=maze[u.x][u.y][u.z]+1;
113             if(up.x==_x&&up.y==_y&&_z==up.z){
114                 OK=true;
115                 time=maze[up.x][up.y][up.z];
116                 break;
117             }
118             q.push(up);
119         }
120         if(down.z>=0&&maze[down.x][down.y][down.z]==0){
121             
122             maze[down.x][down.y][down.z]=maze[u.x][u.y][u.z]+1;
123             if(down.x==_x&&down.y==_y&&_z==down.z){
124                 OK=true;
125                 time=maze[down.x][down.y][down.z];
126                 break;
127             }
128             q.push(down);
129         }
130     }
131     if(OK){
132         cout <<"Escaped in "<<time<<" minute(s)."<<endl;
133     }else{
134         cout <<"Trapped!"<<endl;
135     }
136 }

这个代码虽然能AC,但是存在很多问题:

  • 六个方向导致要写6个i重复度很高的f语句,非常花时间而且代码重复度高
  • 没有利用好每个格子的权值(这个问题在这里已经修复了)

针对第一个问题,可以用三个数组分别记录六个方向的三个坐标的变动,这样可以将6个if语句合为1个

int dx[] = {0,1,0,-1,0,0},dy[] = {1,0,-1,0,0,0},dz[] = {0,0,0,0,1,-1};//拓展操作可以直接定义数组来进行拓展
int x = t.first + dx[i],y = t.second + dy[i],z = t.third + dz[i];

针对第二个问题,应该用每个格子的权值表示从起点到这个格子所需的分钟,这样便巧妙的记录了到达每个格子的所需时间

//时间在格子间的传递
maze[left.x][left.y][left.z]=maze[u.x][u.y][u.z]+1;

本题为典型的BFS模板题,将常见的二维图改成了三维,但是方法没有变。

POJ - 2251 Dungeon Master

原文:https://www.cnblogs.com/shiyu-coder/p/13128558.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!