zoukankan      html  css  js  c++  java
  • hdu 1180:诡异的楼梯(BFS广搜)

    诡异的楼梯

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


    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
    地图如下:
     
    Source
     
    Recommend
    JGShining   |   We have carefully selected several similar problems for you:  1072 1026 1240 1253 1242 

      
      bfs广搜。
      在广搜的基础框架之上加了一个“会旋转的楼梯”,楼梯有2个初始状态 “|” 和 “-” ,每移动一次楼梯就变化一次(| => -  ; - => |)。每移动一次用时一分钟,如果遇到楼梯时,正好能通过,则直接跳到楼梯对面,时间+1(也就是说2个格子只用了1分钟);如果恰好不能通过,则在原地等待1分钟。问从初始位置(S)到终点(T)的最短时间。
      这道题的重点是遇到楼梯的处理,可以先用遇到楼梯时的步数(step)来判断,然后用遇到楼梯时的方向(i)来判断。
      处理方法如下:
     1   if   |    //遇到的楼梯初始是‘|’
     2     if  step是奇数,变化
     3       if  i 是奇数
     4         不能通过
     5       else
     6         能通过
     7     else  //不变
     8       if  i 是奇数
     9         能通过
    10       else
    11         不能通过
    12   if   -    //遇到的楼梯初始是‘-’
    13     if  step是奇数,变化
    14       if  i 是奇数
    15         能通过
    16       else
    17         不能通过
    18     else  //不变
    19       if  i 是奇数
    20         不能通过
    21       else
    22         能通过

    另外注意两点:

      1.剪枝。有一个可以剪枝的地方:遇到楼梯先判断楼梯对面是否走过,如果已经走过,直接退出本次循环。

      2.超时问题。一定要处理好step(遇到楼梯时的步数),因为step是会变的,所以这次如果不能通过,下次也一定能通过。像我一开始把“step”整成了不会变的,测试结果对了,提交却一直超时。

    代码 
      1 #include <iostream>
      2 #include <queue>
      3 #include <string.h>
      4 using namespace std;
      5 char a[21][21];
      6 bool isw[21][21];
      7 int dx[4] = {0,1,0,-1};
      8 int dy[4] = {1,0,-1,0};
      9 int M,N;
     10 int startx,starty;
     11 bool pass;    //能否通过梯子 
     12 struct NODE{
     13     int x;
     14     int y;
     15     int step;
     16 };
     17 int abs(int n)
     18 {
     19     return n>0?n:-n;
     20 }
     21 bool judge(int x,int y,int i,int step)
     22 {
     23     if( x<1 || y<1 || x>M ||y>N )    //越界 
     24         return 1;
     25     if( isw[x][y] )        //走过了 
     26         return 1;
     27     if( a[x][y]=='*' )    //遇到墙
     28         return 1;
     29     if( a[x][y]=='|' ){
     30         if( isw[x+dx[i]][y+dy[i]] )
     31             return 1;
     32         if( step%2 ){    //奇,变 
     33             if( i%2 )    //奇数 
     34                 pass = false;    //不可以通过
     35             else 
     36                 pass = true;    //可以通过
     37         }
     38         else {    //不变 
     39             if( i%2 )    //奇数 
     40                 pass = true;    //可以通过
     41             else 
     42                 pass = false;    //不可以通过
     43         }
     44     }
     45     else if( a[x][y]=='-' ){
     46         if( isw[x+dx[i]][y+dy[i]] )
     47             return 1;
     48         if( step%2 ){    //奇,变 
     49             if( i%2 )    //奇数 
     50                 pass = true;    //可以通过
     51             else 
     52                 pass = false;    //不可以通过
     53         }
     54         else{    //不变 
     55             if( i%2 )    //奇数 
     56                 pass = false;    //不可以通过
     57             else 
     58                 pass = true;    //可以通过
     59         }
     60     }
     61     return 0;
     62 }
     63 int bfs(int x,int y)
     64 {
     65     queue <NODE> q;
     66     NODE cur,next;
     67     cur.x = x;
     68     cur.y = y;
     69     cur.step = 0;
     70     q.push(cur);    //第一个节点入队 
     71     while(!q.empty()){
     72         //队首出队
     73         cur = q.front();
     74         q.pop(); 
     75         if(a[cur.x][cur.y]=='T')    //如果这一步已经走到了终点,则输出走到这一步的步数 
     76             return cur.step;
     77         for(int i=0;i<4;i++){    //下一层节点入队 
     78             int nx = cur.x + dx[i];
     79             int ny = cur.y + dy[i];
     80             if( judge(nx,ny,i,cur.step) )    //判定这一步可走否 
     81                 continue;
     82             if(a[nx][ny]=='|' || a[nx][ny]=='-'){    //如果这一步是碰到梯子的 
     83                 if(pass){    //可以通过梯子 
     84                     nx += dx[i];
     85                     ny += dy[i];
     86                 }
     87                 else{    //不可以通过梯子 
     88                     nx -= dx[i];
     89                     ny -= dy[i];
     90                 }
     91             }
     92             next.x = nx;    //可走,记录下一步的位置 
     93             next.y = ny;
     94             next.step = cur.step + 1;    //可走,步数累加 
     95             isw[next.x][next.y] = true;    //可走,标记走过
     96             q.push(next); 
     97         } 
     98     }
     99 }
    100 int main()
    101 {
    102     while(cin>>M>>N){
    103         for(int i=1;i<=M;i++)
    104             for(int j=1;j<=N;j++){
    105                 cin>>a[i][j];
    106                     if(a[i][j]=='S'){
    107                     startx = i;
    108                     starty = j;
    109                 }
    110             }
    111         memset(isw,0,sizeof(isw));
    112         isw[startx][starty] = true;
    113         cout<<bfs(startx,starty)<<endl;
    114     }
    115     return 0;
    116 }

    Freecode : www.cnblogs.com/yym2013

  • 相关阅读:
    Visual Studio 连接不上NuGet 官方程序包源的解决办法
    Microsoft Toolkit 2.5下载 – 一键激活Windows 8.1/2012 R2/Office 2013
    Intel® Ethernet Connection I217-V 网卡驱动(win10 ,2012)
    flashfxp3.41中文版注册码:(适合最新版本)
    Fiddler对安卓应用手机抓包图文教程
    网址检查器1.0
    Win10打不开chm文件的解决办法
    Android HTTP通讯
    对Android开发者有益的40条优化建议
    IIS下PHP的三种配置方式比较
  • 原文地址:https://www.cnblogs.com/yym2013/p/3522301.html
Copyright © 2011-2022 走看看