• 杭电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 }
  • 相关阅读:
    Hibernate:组合模式解决树的映射
    以面到点的学习MFC
    linux内核--进程与线程
    控件自定义
    火车车次查询-余票查询--Api接口
    如何处理大量数据并发操作(数据库锁机制详解)
    Java单链表、双端链表、有序链表实现
    事务、数据库事务、事务隔离级别、锁的简单总结
    数据库连接池分析
    Spring面试题集
  • 原文地址:https://www.cnblogs.com/fromzore/p/9783741.html
Copyright © 2020-2023  润新知