给你一个地图,让你从起点走到终点,然后图上有空地,墙,还有摄像头,摄像头有初始方向,每一秒摄像头都会顺时针旋转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; }