zoukankan      html  css  js  c++  java
  • hdu5040 不错的广搜

    题意:
          给你一个地图,让你从起点走到终点,然后图上有空地,墙,还有摄像头,摄像头有初始方向,每一秒摄像头都会顺时针旋转90度,每个摄像头有自己的观察范围,它所在的点,和当前它面向的那个点,如果我们当前这一步,和要走的下一步中有一个在当前这个时刻被摄像头监视着,那么我们就必须穿上个东西,穿上这个东西之后就可以不被发现了,但是穿上这个东西后移动速度变成每个格子3秒了,或者我们可以选择当前这一步静止不动。


    思路:

          wa了20多次,哎!,对于每一个点最多可以等两次(有的人说3次),其实就是两次,因为等两次之后最快的方式是+1走到下个点,等于直接用3的那个速度直接走过去,我们开一个数组mark[x][y][w] ,表示的是点x,y等待w次时的最优值,然后开个优先队列(保证第一个出来的答案就是最优的,同时也可以优化时间),然后当前点被监视,或者下一个点被监视的时候,我们就可以原地等待一次。具体看代码。


    #include<stdio.h>
    #include<string.h>
    #include<queue>
    
    #define N 510
    
    using namespace std;
    
    typedef struct NODE
    {
       int x ,y ,t ,w;
       friend bool operator < (NODE a ,NODE b)
       {
          return a.t > b.t;
       }
    }NODE;
    
    NODE xin ,tou;
    int mark[N][N][5];
    int  map[N][N] ,ex ,ey ,n;
    int  dir[4][2] = {0 ,1 ,0 ,-1 ,1 ,0 ,-1 ,0};
    
    bool ok(int x ,int y)
    {
       return x >= 1 && x <= n && y >= 1 && y <= n && map[x][y];
    }
    
    
    int sxj(int x ,int y ,int t)
    {
       if(map[x][y] >= 1 && map[x][y] <= 4) return 1;
       if(x - 1 >= 1 && map[x-1][y] >= 1 && map[x-1][y] <= 4)
       {
          int now = (map[x-1][y] + t) % 4;
          if(!now) now = 4;
          if(now == 3) return 1;
       }
       if(x + 1 <= n && map[x+1][y] >= 1 && map[x+1][y] <= 4)
       {
          int now = (map[x+1][y] + t) % 4;
          if(!now) now = 4;
          if(now == 1) return 1;
       }
       if(y - 1 >= 1 && map[x][y-1] >= 1 && map[x][y-1] <= 4)
       {
          int now = (map[x][y-1] + t) % 4;
          if(!now) now = 4;
          if(now == 2) return 1;
       }
       if(y + 1 <= n && map[x][y+1] >= 1 && map[x][y+1] <= 4)
       {
          int now = (map[x][y+1] + t) % 4;
          if(!now) now = 4;
          if(now == 4) return 1;
       }
       return 0;
    }
    
    
    int BFS(int x ,int y)
    {
       priority_queue<NODE>q;
       xin.x = x ,xin.y = y ,xin.t = xin.w = 0;
       for(int i = 1 ;i <= n ;i ++)
       for(int j = 1 ;j <= n ;j ++)
       for(int k = 0 ;k <= 4 ;k ++)
       mark[i][j][k] = 100000000;
       mark[xin.x][xin.y][xin.w] = 0;
       q.push(xin);
       while(!q.empty())
       {
          tou = q.top();
          q.pop();
          if(tou.x == ex && tou.y == ey) return tou.t;
          for(int i = 0 ;i < 4 ;i ++)
          {
             xin.x = tou.x + dir[i][0];
             xin.y = tou.y + dir[i][1];
             xin.w = 0;
             if(!ok(xin.x ,xin.y)) continue; 
             if(sxj(tou.x ,tou.y ,tou.t) || sxj(xin.x ,xin.y ,tou.t))
             xin.t = tou.t + 3;
             else xin.t = tou.t + 1;
             if(xin.t < mark[xin.x][xin.y][xin.w])
             {
                mark[xin.x][xin.y][xin.w] = xin.t;
                q.push(xin);
             }
          }
          
          xin.x = tou.x ,xin.y = tou.y ;
          xin.t = tou.t + 1 ,xin.w = tou.w + 1;
          if(xin.w <= 2 && xin.t < mark[xin.x][xin.y][xin.w])
          {
             mark[xin.x][xin.y][xin.w] = xin.t;
             q.push(xin);
          }
       }
       return -1;
    }
    
    int main ()
    {
       int t ,i ,j ,x ,y ,cas = 1;
       char str[N];
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d" ,&n);
          for(i = 1 ;i <= n ;i ++)
          {
             scanf("%s" ,str);
             for(j = 0 ;j < n ;j ++)
             {
                if(str[j] == '.') map[i][j+1] = 5;
                if(str[j] == '#') map[i][j+1] = 0;
                if(str[j] == 'N') map[i][j+1] = 1;
                if(str[j] == 'E') map[i][j+1] = 2;
                if(str[j] == 'S') map[i][j+1] = 3;
                if(str[j] == 'W') map[i][j+1] = 4;
                if(str[j] == 'M') map[i][j+1] = 5 ,x = i ,y = j + 1;
                if(str[j] == 'T') map[i][j+1] = 5 ,ex = i ,ey = j + 1;
             }
          }
          printf("Case #%d: %d
    " ,cas ++ ,BFS(x ,y));
       }
       return 0;
    }
    
    
    
             
    

  • 相关阅读:
    LeetCode 623. Add One Row to Tree
    LeetCode 894. All Possible Full Binary Trees
    LeetCode 988. Smallest String Starting From Leaf
    LeetCode 979. Distribute Coins in Binary Tree
    LeetCode 814. Binary Tree Pruning
    LeetCode 951. Flip Equivalent Binary Trees
    LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List
    LeetCode 889. Construct Binary Tree from Preorder and Postorder Traversal
    LeetCode 687. Longest Univalue Path
    LeetCode 428. Serialize and Deserialize N-ary Tree
  • 原文地址:https://www.cnblogs.com/csnd/p/12062760.html
Copyright © 2011-2022 走看看