当前位置: 代码迷 >> 综合 >> POJ 2251 第一次博客
  详细解决方案

POJ 2251 第一次博客

热度:29   发布时间:2023-12-01 01:51:14.0

都说万事开头难,所以我要找一个简单的题目来写我的第一次题解。我的成长从此开始,不会再止步不前。

题目:你被困在一个3D地牢里,需要找到最快的出路!地牢由单位立方体组成,这些立方体可能充满也可能不充满岩石。将一个单元向北、向南、向东、向西、向上或向下移动需要一分钟。你不能沿对角线移动,迷宫四面都被坚固的岩石包围着。可以逃脱吗?如果是,需要多长时间?

解题方法:一道很简单的bfs题,只需要主要多出来的俩个方向就可以了。

宽度优先搜索算法(又称广度优先搜索)是最简便的图的搜索算法之一,这一算法也是很多重要的图的算法的原型。Dijkstra单源最短路径算法和Prim最小生成树算法都采用了和宽度优先搜索类似的思想。其别名又叫BFS,属于一种盲目搜寻法,目的是系统地展开并检查图中的所有节点,以找寻结果。换句话说,它并不考虑结果的可能位置,彻底地搜索整张图,直到找到结果为止。

   那在我看来呢,当你很清楚的知道图该如何走的时候就可以用到bfs。比如现在这个题目,我们很明确的知道有六个方向也很明确的知道这个地图,所以我就可以用到bfs。

  然后bfs需要一些什么呢?(我们一直从现在的起点走到终点需要知道什么)

1:知道现在的位置以及接下来的位置。

2:什么地方是不能走的。

  对于第一个问题,在bfs中我们采用队列,存储住你当时所在的位置,然后在用方向数组,当你用方向数组的坐标加上现在位置的坐标时你就可以得出你想要去的下一个位置了。

  那不能走的位置呢,第一个就是题目中给到的不能走的位置,第二个就是我们已经走过的位置。显然第一个问题很容易知道,第二个问题我们需要借助一个数组来完成,我们可以用一个visit数组来确定这个位置是否被我们走过。

  当我们把问题都解决之后那我们解决题目就很容易了。

工具:图,visit数组,结构体队列,方向数组,结构体(是一个很好的记录当前位置的方式)。

过程:首先我们输入图,然后找出我们的起点用一个结构体记录下来,然后开始bfs。

bfs:

第一步:将起点记录进队列,然后用visit数组将这个点记录为不可再次查询。

第二步:我们要队列里的很多的点,所以我们一定会用到循环,那我们就需要找到循环的出口,很容易知道当队列为空的时候或者我们找到了终点的时候循环就可以结束了。那我们设立一个循环,然后每次循环的开始都从队列的头元素开始(记住此时一定要把头元素从队列中取出来),然后找到接下来你要去的坐标,将这些坐标判断是否能走,如果能走就将此点的信息(照题目的要求将一些变量进行改变,例如这个题目中的每走一步就会用到1s中,所以每走一步我们就要将走到的坐标以及现在的时间加上1然后加入队列中) 还有一定要记住走到终点时我们也需要退出这个循环。这样的话bfs过程就解决了

  因为我也写完了那个专题,也有十几个搜索题目了,我发现我们需要学的第一是思考方式,然后 就是模板,例如bfs怎么写就是模板。

  在解题时呢,我们一定要抓住题目的特性和共性,特性就是这个题目与你脑海中有的你写过的题目的区别,我们将这些特性解决,然后就是与那些题目有什么相同的地方,相同的地方记住,下次就不用再花多的时间思考相同点了。

  最后时代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
int idx[]={0,0,0,0,1,-1};//
int idy[]={0,0,1,-1,0,0};//
int idz[]={-1,1,0,0,0,0};// 三个加在一起就是方向数组
char maze[35][35][35];//图
char v[35][35][35];//标记数组
using namespace std;
int l,r,c;//l层 r行 c列
typedef struct node
{int x,y,z;int t;
}Node;
Node S,E;
bool bfs()
{queue<Node>q;v[S.x][S.y][S.z]=true;q.push(S);while(!q.empty()){Node t=q.front();q.pop();for(int i=0;i<6;i++){int x=t.x+idx[i];int y=t.y+idy[i];int z=t.z+idz[i];int d=t.t;if(x>=0&&x<l&&y>=0&&y<r&&z>=0&&z<c&&!v[x][y][z])//判断此点是否可以通过{if(maze[x][y][z]=='.'){q.push({x,y,z,d+1});v[x][y][z]=true;}}if(maze[x][y][z]=='E'){E.t=d+1;return true;//如果搜索所有我们可以走到的点 到了终点就返回是}}}return false;//如果我们可以走的所有的点都搜索完了还是不行,那就返回否
}
int main()
{while(cin >>l>>r>>c&&(l+r+c)){memset(v,false,sizeof(v));//记得每次都要更新for(int i=0;i<l;i++)for(int j=0;j<r;j++)for(int k=0;k<c;k++){cin>>maze[i][j][k];if(maze[i][j][k]=='S'){S.x=i;S.y=j;S.z=k;S.t=0;}}if(bfs())printf("Escaped in %d minute(s).\n",E.t);elsecout <<"Trapped!"<<endl;}return 0;
}