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): 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
    ", 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                         else
    46                         {
    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 }
  • 相关阅读:
    完全备份、差异备份以及增量备份的区别(转)
    Backup Exec Inventory 与Catalog的含义(转载)
    从客户端中检测到有潜在危险的Request.Form值的解决办法
    IQueryable与IEnumberable的区别(转)
    SQL递归查询(with cte as) 物料分解
    Http权威指南笔记(二) Http状态码大全
    Http权威指南笔记(一) URI URL URN 关系
    echarts在.Net中使用实例(二) 使用ajax动态加载数据
    echarts在.Net中使用实例(一) 简单的Demo
    sql显示12个月数据
  • 原文地址:https://www.cnblogs.com/titicia/p/3895996.html
Copyright © 2011-2022 走看看