hdu 1180:诡异的楼梯

诡异的楼梯

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
hdu 1180:诡异的楼梯
5 5
**..T
**.*.
..|..
.*.*.
S....
hdu 1180:诡异的楼梯

 

Sample Output
7
 
Hint
Hint
地图如下: hdu 1180:诡异的楼梯
 

 

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)来判断。
  处理方法如下:
hdu 1180:诡异的楼梯
 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         能通过
hdu 1180:诡异的楼梯

另外注意两点:

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

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

代码 
hdu 1180:诡异的楼梯
  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 }
hdu 1180:诡异的楼梯

 

Freecode : www.cnblogs.com/yym2013

hdu 1180:诡异的楼梯

上一篇:Java|语法结构


下一篇:python的中文输入