hdu5040 不错的广搜<旋转的摄像头>

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


思路:

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


#include<stdio.h>#include<string.h>#include<queue>#define N 510using 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\n" ,cas ++ ,BFS(x ,y));   }   return 0;}         

0 0
原创粉丝点击