hdu5040 不错的广搜<旋转的摄像头>
来源:互联网 发布:php前端网站 编辑:程序博客网 时间:2024/06/14 23:09
题意:
给你一个地图,让你从起点走到终点,然后图上有空地,墙,还有摄像头,摄像头有初始方向,每一秒摄像头都会顺时针旋转90度,每个摄像头有自己的观察范围,它所在的点,和当前它面向的那个点,如果我们当前这一步,和要走的下一步中有一个在当前这个时刻被摄像头监视着,那么我们就必须穿上个东西,穿上这个东西之后就可以不被发现了,但是穿上这个东西后移动速度变成每个格子3秒了,或者我们可以选择当前这一步静止不动。
思路:
给你一个地图,让你从起点走到终点,然后图上有空地,墙,还有摄像头,摄像头有初始方向,每一秒摄像头都会顺时针旋转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
- hdu5040 不错的广搜<旋转的摄像头>
- hdu 4528 马拉松不错的广搜
- 旋转的摄像头
- hdu 3004 不错的搜索题(广搜)
- 预处理的广搜
- 广搜的学习
- hdu5040
- hdu5040
- 关于广搜的学习
- 母亲的牛奶【广搜】
- MX的密码锁 (广搜)
- 一个写得非常不错的俄罗斯广块的实现。
- 广搜与深搜的区别
- 图的深搜与广搜
- 图的深搜与广搜
- 深搜和广搜的区别
- 深搜与广搜的特点
- 深搜与广搜的区别
- Cocos2d-X 在MAC中创建项目
- 复变函数及应用 第四章学习感受
- 转:如何高效地判断数组中是否包含某特定值
- POJ 2488(dfs+字典序)
- 大学老师劝告大学生:千万不要成为这十种人
- hdu5040 不错的广搜<旋转的摄像头>
- CF#246 (Div. 2) A.
- cv::Mat成员函数 at(int row,int col)
- 我的项目8 css属性,实现阅读器重排版功能
- duilib CPaintManagerUI的WM_PAINT消息
- 实例介绍Cocos2d-x物理引擎:HelloPhysicsWorld
- 开发板中为用户设置密码出现unknown uid 0的解决办法
- HDU-#5035 Delivery(概率)
- poj 2503 Babelfish(STL map写法)