HDU 5040 Instrusive(最短路)

题目 : http://acm.hdu.edu.cn/showproblem.php?pid=5040

题意 : 从‘M‘ 到  ‘T‘ 最短路程,每次只能走四个方向,并且有一些摄像头每个时间点都会转变下方向(初始方向给出).你有一个box,你在没有罩box的情况下不能被照到,可以在点上等待,也可以罩着box走(时间会慢成3个单位)。

思路 : 就是一个最短路问题,只要算出在当前时间点u->v最多要花多时间才能到就行了(最多是3),用spfa跑。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <vector>
  5 #include <queue>
  6
  7 using namespace std;
  8 typedef pair<int, int> PII;
  9 const int MAXN = 505;
 10 const int dir[4][2] = {-1, 0, 0, 1, 1, 0, 0, -1}; // N E S W
 11 const int INF = 0x3f3f3f3f;
 12
 13 struct A {
 14     int x, y;
 15     A() {}
 16     A(int a, int b):x(a), y(b) {}
 17 };
 18
 19 char maze[MAXN][MAXN];
 20 int dis[MAXN][MAXN];
 21 int vis[MAXN][MAXN];
 22 int n;
 23 int sx, sy, ex, ey;
 24
 25 PII change(int x, int y, int tim) {
 26     int add;
 27     if (maze[x][y] == ‘N‘) add = 0;
 28     if (maze[x][y] == ‘E‘) add = 1;
 29     if (maze[x][y] == ‘S‘) add = 2;
 30     if (maze[x][y] == ‘W‘) add = 3;
 31     add = (add + tim) % 4;
 32     return make_pair(x + dir[add][0], y + dir[add][1]);
 33 }
 34 int isok(int x, int y, int tim) {
 35     if (maze[x][y] == ‘N‘ || maze[x][y] == ‘S‘ || maze[x][y] == ‘E‘ || maze[x][y] == ‘W‘) {
 36         return 0;
 37     }
 38     for (int i = 0; i < 4; i++) {
 39         int X = x + dir[i][0];
 40         int Y = y + dir[i][1];
 41         if (maze[X][Y] == ‘N‘ || maze[X][Y] == ‘S‘ || maze[X][Y] == ‘E‘ || maze[X][Y] == ‘W‘) {
 42             PII tmp = change(X, Y, tim);
 43             if (tmp.first == x && tmp.second == y) return 0;
 44         }
 45     }
 46     return 1;
 47 }
 48 int calc(int nx, int ny, int nex, int ney, int tim) {
 49     for (int i = 0; i <= 2; i++) {
 50         if (isok(nx, ny, tim + i) && isok(nex, ney, tim + i)) {
 51             return i + 1;
 52         }
 53     }
 54     return 3;
 55 }
 56
 57 int spfa() {
 58     queue<A> Q;
 59     memset(vis, 0, sizeof(vis));
 60     vis[sx][sy] = 1;
 61     Q.push(A(sx, sy));
 62     memset(dis, INF, sizeof(dis));
 63     dis[sx][sy] = 0;
 64     while (!Q.empty()) {
 65         A e = Q.front(); Q.pop();
 66         int X = e.x;
 67         int Y = e.y;
 68         int now = dis[X][Y];
 69         vis[X][Y] = 0;
 70         for (int i = 0; i < 4; i++) {
 71             int x = X + dir[i][0];
 72             int y = Y + dir[i][1];
 73             if (x <= 0 || y <= 0 || x > n || y > n || maze[x][y] == ‘#‘) {
 74                 continue;
 75             }
 76             int d = calc(X, Y, x, y, now);
 77             if (dis[x][y] > now + d) {
 78                 dis[x][y] = now + d;
 79                 if (!vis[x][y]) {
 80                     vis[x][y] = 1;
 81                     Q.push(A(x, y));
 82                 }
 83             }
 84         }
 85     }
 86     return dis[ex][ey] == INF ? -1 : dis[ex][ey];
 87 }
 88
 89 int main() {
 90     int T;
 91     scanf("%d", &T);
 92     for (int cas = 1; cas <= T; cas++) {
 93         scanf("%d", &n);
 94         for (int i = 1; i <= n; i++) {
 95             scanf("%s", maze[i] + 1);
 96         }
 97         for (int i = 1; i <= n; i++) {
 98             for (int j = 1; j <= n; j++) {
 99                 if (maze[i][j] == ‘M‘) {
100                     sx = i; sy = j;
101                 }
102                 if (maze[i][j] == ‘T‘) {
103                     ex = i; ey = j;
104                 }
105             }
106         }
107         printf("Case #%d: %d\n", cas, spfa());
108     }
109     return 0;
110 }
111 /*
112 111
113 3
114 #S#
115 WM.
116 #WT
117 */

时间: 2024-10-15 13:23:39

HDU 5040 Instrusive(最短路)的相关文章

HDU 5040 Instrusive(北京网络赛I题)

HDU 5040 Instrusive 题目链接 思路:记忆化广搜,先预处理出图,每个位置用一个二进制数表示,表示4秒为1个周期内,这个位置是否会被照到,然后进行记忆化广搜即可,状态多开一个4,表示在4秒一周期,然后进行转移即可 代码: #include <cstdio> #include <cstring> #include <queue> using namespace std; const int N = 505; const int d[4][2] = {-1,

hdu 5040 Instrusive【BFS+优先队列】

2014北京网络赛09题,hdu 5040 这次网络赛真是惨,也怪做题策略没想好,当时切完签到题之类的水题之后,马上就去看06青蛙那题去了.结果被那只死青蛙给坑惨了T_T...搞了四小时没搞出来...跪给那只青蛙了...本来当时是准备要做这道题的,题目描述也是好蛋疼,有人说这题不如直接去看Clarification,不看题目了,这也说明这题题目描述确实不清晰,虽然没这么夸张,题目还是得看的. 重新看这道题,不是很难,最短时间的话,那当然想到BFS,纯BFS的话,只是最短步数,所以我们需要+优先队

HDU 5040 Instrusive

题目链接~~> 做题感悟:这题在网络赛的时候没有解出来,当时最后才写的有点慌了,so~>思路一点不清楚. 解题思路: 这题首先弄清楚在走每一步的时候是人先走,还是摄像头先走,当然是人先走,如果一个人从 A ---> B ,那么需要判断前一秒A 和 B 是否被摄像头照到,因为人先走,如果曾被摄像头找到,那么走过去会被发现,这样可以选择等一秒,下一秒同样再判断一次,如果还是不可以,就需要带着箱子走.还要注意时间第一秒时摄像头转到先一个方向.因为时间不是都加 1 ,需要用优先队列,同时一个点可

HDU 5040 Instrusive BFS

如果题意明确了的话就是一个简单bfs...... 用优先队列搞一下还是很快的. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque> #inc

2014 ACM/ICPC Asia Regional Beijing Online HDU 5040 Instrusive 优先队列

WA到死的一道题目. 一个人从起点走到目标点.这个过程中有摄像头,摄像头的照射范围为两个单位长度,包括摄像头自己的位置.为了避免被照射到,可以有两种选择. 在一个位置等待1S,或者坐在盒子里过去(花费3S),走一步花费1S.摄像头每秒顺时针转一次. 1.4S有一个循环,所以每个位置vis[r][c][sec] 四种情况的最优解 2.不用显示构图, 每个摄像头都记录一下四种情况 3.使用优先队列,判断 RE,TLE,WA,AC..... 刚开始每个摄像头旋转的时候没有判断是否在范围内,一直RE,起

2014年北京网络赛 Instrusive HDU 5040 题解 优先队列

网赛的时候看了这道题,发现就是平常的那种基础搜索题. 由于加了一个特殊条件:可以一次消耗3秒或原地停留1秒. 那就不能使用简单的队列了,需要使用优先队列才行. 题意 告诉一副地图:一个起点,一个终点,若干墙,若干监视器,剩下的是空地. 起点,终点,监视器都算空地. 监视器初始值会指定一个方向,共有四个方向. 监视器每秒顺时针转动到下个方向. 监视器视野距离为2. 在监视器的位置或在监视器面向的格子是监视区域. 普通的移动一格需要消耗1秒时间. 在监视器下移动一格需要消耗3秒时间. 如果呆在原地不

HDU 2544:最短路( 最短路径入门 &amp;&amp;Dijkstra &amp;&amp; floyd )

最短路 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 30972    Accepted Submission(s): 13345 Problem Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找

hdu 2112 HDU Today (最短路)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2112 题目大意:给出起点和终点,然后算出最短的路. 不过有好多细节要注意: (1)起始点和终止点相等的时候,这里注意不能直接输出0,必须用标记,因为数据可能还没有处理完!!!此处贡献n次wa. (2)这里是某大神教我的用map进行转换,将字符串转换成数字,值得参考.map<string,int>M,V:不过这里同样是wa了好多次.要注意的是将最先输入的开始和结束的点也要放到这个map里面. (3)

hdu 4568 Hunter 最短路+dp

Hunter Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2014    Accepted Submission(s): 615 Problem Description One day, a hunter named James went to a mysterious area to find the treasures. Jame