首页 > 代码库 > hdu 1180 诡异的楼梯(BFS)

hdu 1180 诡异的楼梯(BFS)

诡异的楼梯

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


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
地图如下:
 

 

就是遇到楼梯如果对面的已经访问过,就不用走了,如果对面的没有访问过,如果能直接过,能一下子走2格,如果不能直接过,等楼梯移过来,因为这样时间跟走过去相同,

也不会多。

 

  1 #include <iostream>  2 #include <cstring>  3 #include <string>  4 #include <cstdio>  5 #include <queue>  6 using namespace std;  7 #define maxn 25  8 char mp[maxn][maxn];  9 int vis[maxn][maxn], M, N, sx, sy, tx, ty, ans; 10 int dir[4][2] = {{0,1}, {0,-1}, {-1,0},{1,0}}; //4个方向  11 struct node{ 12     int x, y, t; 13 }; 14 bool judge(int x, int y){ 15     if(x >= 0 && x < M && y >= 0 && y < N && mp[x][y] != * && !vis[x][y]) return 1; 16     return 0; 17 } 18 bool judgeBridge(int x, int y, int t, int dir){ //注意这里要算前一秒的!!!!因为还没走  19     if(mp[x][y] == |) //如果一开始是竖的话  20     { 21         if(t%2==0 && (dir == 2 || dir == 3)) //如果还是竖的,且走的也是竖的  22             return 1 ; 23         else if(t%2 && (dir == 0 || dir == 1)) //如果是横的而且走的也是横的,  24             return 1 ; 25     } 26     else if(mp[x][y] == -)  //如果一开始是横的话  27     { 28         if(t%2==0 && (dir == 0 || dir == 1))  //如果还是横的,且走的也是横的  29             return 1; 30         else if(t%2 && (dir == 2 || dir == 3)) 31             return 1; 32     } 33     return 0; 34 }  35 node q[maxn*maxn]; 36 int BFS(int sx, int sy){ 37     memset(vis, 0, sizeof(vis)); 38     int front = 0, rear = 1; 39     q[front].x = sx; q[front].y = sy; q[front].t = 0; 40     vis[sx][sy] = 1; 41     while(front < rear){ 42         int x = q[front].x;  43         int y = q[front].y; 44         int t = q[front].t; 45         front++; 46         if(x == tx && y == ty) return t;  //如果已经到了终点,跳出 47         for(int i = 0; i < 4; i++){ 48             int nx = x+dir[i][0]; 49             int ny = y+dir[i][1]; 50             if(judge(nx, ny)){ 51                 if(mp[nx][ny] == .){ 52                     vis[nx][ny] = 1; 53                     node temp; 54                     temp.x = nx; 55                     temp.y = ny; 56                     temp.t = t+1; 57                     q[rear++] = temp; 58                 } 59                 else{ 60                     int nnx = nx + dir[i][0]; 61                     int nny = ny + dir[i][1]; //过桥  62                     if(judge(nnx, nny)){ //如果桥对面的点没有访问过的话  63                         if(judgeBridge(nx, ny, t,i )){ //过桥  64                             vis[nnx][nny] = 1; 65                             node temp; 66                             temp.x = nnx; 67                             temp.y = nny; 68                             temp.t = t+1; 69                             q[rear++] = temp; 70                         } 71                         else{       //等待  72                             node temp; 73                             temp.x = x; 74                             temp.y = y; 75                             temp.t = t+1; 76                             q[rear++] = temp; 77                         } 78                     }  79                 } 80             } 81         }  82           83     }  84     return -1;  85 }  86 int main(){ 87     while(~scanf("%d%d", &M, &N)){ 88         for(int i = 0; i < M; i++){ 89             for(int j = 0; j < N; j++){ 90                 cin>>mp[i][j]; 91             } 92         } 93         for(int i = 0; i < M; i++){ 94             for(int j = 0; j < N; j++){ 95                 if(mp[i][j] == S){ 96                     mp[i][j] = .; 97                     sx = i; sy = j; 98                 } 99                 if(mp[i][j] == T){100                     mp[i][j] =.;101                     tx = i; ty = j;102                 }103             }104         }105         106         ans = BFS(sx, sy);107         printf("%d\n", ans);108     }109     110     return 0;111 }

 

 

根据这题来个BFS模板吧

 1 int bfs(int sx,int sy) //初始位置  2 { 3     memset(vis, 0 ,sizeof(vis));                            //清空访问数组  4     int head = 0,tail=1;                                //头是0, 尾是1, 因为要加入一个数,就是初始位置           5     que[head].x=sx ,que[head].y=sy ,que[head].step = 0; //把初始位置加入队列。  6     vis[sx][sy] = 1 ;                                   //初始位置标记已经访问过  7     while(head < tail)                                  //当队列不为空的时候  8     { 9         int x = que[head].x;10         int y = que[head].y;11         int step = que[head].step;  //拿出队首元素 12         head++ ;                    //弹出 13         if(x == ex && y == ey)      //如果已经走到终点,退出循环 14         {15             return step ;16         }17         //如果没有结束 18         for(int i = 0 ; i < 4 ;i++){  //走上下左右4个方向 19             int nx = x+d[i][0]20             int ny = y+d[i][1] ;21             if(judge(nx, ny)){       //判断满足的条件 ,如果可以走 22                 if(map[nx][ny] == .){ //如果不是楼梯直接入列 23                     vis[nx][ny] = 1 ;   //标记已经访问过 24                     que[tail].x = nx ;  25                     que[tail].y = ny ;26                     que[tail].step = step+1 ;27                     tail++;             //加入队列 28                 }29                 else//如果是楼梯 30                 {31                     int nnx = nx + d[i][0] , nny = ny + d[i][1] ;32                     //楼梯对面的点没有访问过33                     if(judge(nnx, nny))34                     {35                         if(goStair(nx, ny, step,i))36                             //判断楼梯此时是否可走37                         {38                             //如果可走则直接将该点放入队列,标记为已访问39                             vis[nnx][nny] = 1;40                             que[tail].x = nnx ;41                             que[tail].y = nny;42                             que[tail].step = step+1 ;43                             tail++ ;44                         }45                         else46                         {47                             //如果此时楼梯不能走,则将此时所在的点放回队尾(等待)48                             que[tail].x = x ;49                             que[tail].y = y ;50                             que[tail].step = step+1 ;51                             tail++ ;52                         }53                     }54                 }55             }56         }57     }58     return -1 ;59 }