poj 2251
题目大意:这题是一个三维的迷宫题目,其中用'.'表示空地,'#'表示障碍物,'S'表示起点,'E'表示终点,求从起点到终点的最小移动次数,解法和二维的类似,只是在行动时除了东南西北移动外还多了上下。
对于题目给出数据的含义就是输入l,r,c,分别代表迷宫有l层,每层长宽分别是c,r。
对于数据以可以这样移动
(1,1,1)->(1,1,2)->(1,1,3)->(1,1,4)->(1,1,5)->(1,2,5)
->(1,3,5)->(1,3,4)->(1,4,4)->(2,4,4)->(2,4,5)->(3,4,,5)
共11步就可以到达终点
对于数据二明显不能到达,则输出Trapped
这题用BFS解,每次去队首元素,如果是终点则输出结果移动的次数,否则,从该点开始分别向东南西北上下移动(如果可以走的话)并继续搜,如果到队列为空还没搜到解法,则说明无解。
这题我提交一次就AC了,可以看出难度不是很大。
典型的最短到达问题 简单
#include<iostream> #include<queue> #include<cstring> using namespace std; int dir[6][3]={-1,0,0,1,0,0,0,-1,0,0,1,0,0,0,1,0,0,-1}; char map[33][33][33]; int v[33][33][33]; int INF=99999999; struct Node { int x,y,z; int t; }; int Z,X,Y; int step; int sz,sx,sy,ez,ex,ey; void bfs() { int i; queue<Node> q; Node now,next; now.x=sx,now.y=sy,now.z=sz; now.t=0; q.push(now); while(!q.empty()) { now=q.front(); if(now.z==ez&&now.x==ex&&now.y==ey) break; q.pop(); for(i=0;i<6;i++) { int xx=now.x+dir[i][0]; int yy=now.y+dir[i][1]; int zz=now.z+dir[i][2]; if(xx>X||xx<=0||yy>Y||yy<=0||zz>Z||zz<=0) continue; if(map[zz][xx][yy]=='#') continue; if(v[zz][xx][yy]>now.t+1)//这里是bfs的最重要的步骤 减枝 简单的比较好求 以后会遇到很复杂的问题 { v[zz][xx][yy]=now.t+1; next.x=xx;next.y=yy,next.z=zz; next.t=now.t+1; q.push(next); } } } if(v[ez][ex][ey]<INF) cout<<"Escaped in "<<v[ez][ex][ey]<<" minute(s)."<<endl; else cout<<"Trapped!"<<endl; } int main() { int i,j,k; while(cin>>Z>>X>>Y) { if(Z==0&&X==0&&Y==0) break; step=999999999; for(i=1;i<=Z;i++) for(j=1;j<=X;j++) for(k=1;k<=Y;k++) { v[i][j][k]=INF; cin>>map[i][j][k]; if(map[i][j][k]=='S') sz=i,sx=j,sy=k; if(map[i][j][k]=='E') ez=i,ex=j,ey=k; } bfs(); } return 0; }