杭电acm 1180 诡异的楼梯 BFS

Posted fromzore

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了杭电acm 1180 诡异的楼梯 BFS相关的知识,希望对你有一定的参考价值。

诡异的楼梯

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 19334    Accepted Submission(s): 5048

Problem Description

Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向.
比如下面的例子里,一开始楼梯在竖直方向,一分钟以后它移动到了水平方向,再过一分钟它又回到了竖直方向.Harry发现对他来说很难找到能使得他最快到达目的地的路线,这时Ron(Harry最好的朋友)告诉Harry正好有一个魔法道具可以帮助他寻找这样的路线,而那个魔法道具上的咒语,正是由你纂写的.
 
Input
测试数据有多组,每组的表述如下:
第一行有两个数,M和N,接下来是一个M行N列的地图,‘*‘表示障碍物,‘.‘表示走廊,‘|‘或者‘-‘表示一个楼梯,并且标明了它在一开始时所处的位置:‘|‘表示的楼梯在最开始是竖直方向,‘-‘表示的楼梯在一开始是水平方向.地图中还有一个‘S‘是起点,‘T‘是目标,0<=M,N<=20,地图中不会出现两个相连的梯子.Harry每秒只能停留在‘.‘或‘S‘和‘T‘所标记的格子内.
 
 Output
只有一行,包含一个数T,表示到达目标的最短时间.
注意:Harry只能每次走到相邻的格子而不能斜走,每移动一次恰好为一分钟,并且Harry登上楼梯并经过楼梯到达对面的整个过程只需要一分钟,Harry从来不在楼梯上停留.并且每次楼梯都恰好在Harry移动完毕以后才改变方向.
 

 

Sample Input
5 5
**..T
**.*.
..|..
.*.*.
S....
 

 

Sample Output
7
Hint
Hint
地图如下: 技术分享图片
 
这道题和逃出迷宫一样都是使用BFS算法,但是不同的是他要求的是时间,所以有部分修改了,注意。
  1 #include<iostream>
  2 #include<queue>
  3 #include<string.h>
  4 using namespace std;
  5 
  6 struct Node{
  7     int x,y,time;
  8 }; 
  9 int M,N;//地图大小 
 10 char map[25][25];
 11 int vis[25][25];
 12 int xy[4][2]={0,1,0,-1,1,0,-1,0};//方向 
 13 int start_x,start_y,end_x,end_y;//初始点和结束点 
 14 queue<Node>que;
 15 Node node;
 16 
 17 bool check(int x,int y){//检查当前点能不能走,是不是走过的 
 18     if(x>=0&&x<M&&y>=0&&y<N&&map[x][y]!=*&&!vis[x][y])
 19     return true;
 20     else return false;
 21 }
 22 bool check(int x,int y,int z){//检测当遇到楼梯时,楼梯对面能不能走 
 23     if(z==N){
 24     if(y>=0&&y<z&&map[x][y]!=*&&!vis[x][y])
 25     return true;
 26     else return false;
 27     }
 28     else {
 29         if(x>=0&&x<M&&map[x][y]!=*&&!vis[x][y])
 30         return true;
 31         else return false;
 32     }
 33 }
 34 void push_p(int x,int y,int time){//用来保存每个没有走过的点 
 35         Node temp;
 36         temp.x=x;temp.y=y;temp.time=time+1;
 37         que.push(temp);
 38         return;
 39 } 
 40 
 41 int BFS(){
 42     int fx,fy;//是下一步将要走到的坐标 
 43     node.x=start_x;
 44     node.y=start_y;
 45     node.time=0;
 46     que.push(node);
 47     while(!que.empty()){
 48         node=que.front();
 49         que.pop();
 50         if(node.x==end_x&&node.y==end_y){//到达终点 
 51             return node.time;
 52         }
 53         for(int i=0;i<4;++i){//4个方向走 
 54             fx=node.x+xy[i][0];
 55             fy=node.y+xy[i][1];
 56             if(check(fx,fy)){//检查下一个点能不能走 
 57                 if(map[fx][fy]==.||map[fx][fy]==T){//如果不是楼梯,就保存下下一个能走的点 
 58                     push_p(fx,fy,node.time);
 59                     vis[fx][fy]=1;
 60                 }
 61                 else if(map[fx][fy]==-){//如果地图上是横着的楼梯 
 62                     if(node.time%2==0){//那么在偶数时间 它是横着的楼梯 
 63                         if(fx==node.x){//看看他是不是横着走过来的 
 64                             if(node.y+1==fy){
 65                                 fy+=1;
 66                             }
 67                             else{
 68                                 fy-=1;
 69                             }
 70                             if(check(fx,fy,N)){//检查楼梯对面 能不能走 
 71                                 push_p(fx,fy,node.time);
 72                                 vis[fx][fy]=1;
 73                             }
 74                         }
 75                         else{//如果不是横着走过来的就停下等候楼梯 
 76                             push_p(node.x,node.y,node.time);
 77                         }
 78                     }
 79                     else if(node.time%2!=0){//在奇数时间,它是纵着的楼梯 
 80                         if(fy==node.y){//判断他是不是纵着走过来的 
 81                             if(node.x+1==fx){ 
 82                                 fx++;
 83                             }
 84                             else{
 85                                 fx--;
 86                             }
 87                             if(check(fx,fy,M)){//判断他能不能到达楼梯对面 
 88                                 push_p(fx,fy,node.time);
 89                                 vis[fx][fy]=1;
 90                             }
 91                         }
 92                         else{//如果不是纵着走过来的就停下等候楼梯 
 93                         push_p(node.x,node.y,node.time);
 94                         }
 95                     }
 96                 }
 97                 else if(map[fx][fy]==|){//如果地图上的楼梯是纵着的,意思同上 
 98                     if(node.time%2==0){
 99                         if(fy==node.y){
100                             if(node.x+1==fx) fx++;
101                             else fx--;
102                         if(check(fx,fy,M)){
103                             push_p(fx,fy,node.time);
104                             vis[fx][fy]=1;
105                         }
106                     }
107                     else{
108                     push_p(node.x,node.y,node.time);
109                     }
110                 }
111                 else{
112                         if(fx==node.x){
113                             if(node.y+1==fy)fy++;
114                             else fy--;
115                             if(check(fx,fy,N)){
116                                 push_p(fx,fy,node.time);
117                                 vis[fx][fy]=1;
118                             }
119                         }
120                         else{
121                             push_p(node.x,node.y,node.time);
122                         }
123                     }
124                 }
125             }
126         }
127     }
128 }
129 int main(){
130     while(cin>>M>>N){
131         memset(vis,0,sizeof(vis));//初始化用来保存地图上哪个点已经被走过的参数 
132         for(int i=0;i<M;i++){//保存下地图 
133             for(int j=0;j<N;j++){
134                 cin>>map[i][j];
135                 if(map[i][j]==S||map[i][j]==s){//标记初始点 
136                     start_x=i;
137                     start_y=j;
138                 }
139                 if(map[i][j]==T||map[i][j]==t){//标记结束点 
140                     end_x=i;
141                     end_y=j;
142                 }
143             }
144         }
145         vis[start_x][start_y]=1;//初始点被走过 
146         while(!que.empty()){//清空队列 
147             que.pop();
148         }
149         int ans=BFS();//获得所走的时间 
150         cout<<ans<<endl;
151     }
152 }

 







以上是关于杭电acm 1180 诡异的楼梯 BFS的主要内容,如果未能解决你的问题,请参考以下文章

HDU 1180 诡异的楼梯 (搜索)

HDU 1180 诡异的楼梯BFS/楼梯随时间变化

诡异的楼梯 HDU1180

HDU 诡异的楼梯 (bfs)

hdu 1180(广搜好题)

1180: 零起点学算法87——超级楼梯(有疑问)