HDU 3533 Escape (BFS + 预处理)

Escape

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 541    Accepted Submission(s): 141

Problem Description

The students of the HEU are maneuvering for their military training. The red army and the blue army are at war today. The blue army finds that Little A is the spy of the red army, so Little A has to escape from the headquarters of the blue army to that of the red army. The battle field is a rectangle of size m*n, and the headquarters of the blue army and the red army are placed at (0, 0) and (m, n), respectively, which means that Little A will go from (0, 0) to (m, n). The picture below denotes the shape of the battle field and the notation of directions that we will use later.The blue army is eager to revenge, so it tries its best to kill Little A during his escape. The blue army places many castles, which will shoot to a fixed direction periodically. It costs Little A one unit of energy per second, whether he moves or not. If he uses up all his energy or gets shot at sometime, then he fails. Little A can move north, south, east or west, one unit per second. Note he may stay at times in order not to be shot. To simplify the problem, let’s assume that Little A cannot stop in the middle of a second. He will neither get shot nor block the bullet during his move, which means that a bullet can only kill Little A at positions with integer coordinates. Consider the example below. The bullet moves from (0, 3) to (0, 0) at the speed of 3 units per second, and Little A moves from (0, 0) to (0, 1) at the speed of 1 unit per second. Then Little A is not killed. But if the bullet moves 2 units per second in the above example, Little A will be killed at (0, 1). Now, please tell Little A whether he can escape.

Input

For every test case, the first line has four integers, m, n, k and d (2<=m, n<=100, 0<=k<=100, m+ n<=d<=1000). m and n are the size of the battle ground, k is the number of castles and d is the units of energy Little A initially has. The next k lines describe the castles each. Each line contains a character c and four integers, t, v, x and y. Here c is ‘N’, ‘S’, ‘E’ or ‘W’ giving the direction to which the castle shoots, t is the period, v is the velocity of the bullets shot (i.e. units passed per second), and (x, y) is the location of the castle. Here we suppose that if a castle is shot by other castles, it will block others’ shots but will NOT be destroyed. And two bullets will pass each other without affecting their directions and velocities. All castles begin to shoot when Little A starts to escape. Proceed to the end of file.

Output

If Little A can escape, print the minimum time required in seconds on a single line. Otherwise print “Bad luck!” without quotes.

Sample Input

4 4 3 10 N 1 1 1 1 W 1 1 3 2 W 2 1 2 4 4 4 3 10 N 1 1 1 1 W 1 1 3 2 W 1 1 2 4

Sample Output

9 Bad luck!

非常纠结的一题,做了很久才做出来,题意非常不清楚,不推荐这题。

坑点:有碉堡的点不能走,人不会往回走,终点可能有碉堡。

先把所有可能被炮弹打到的点以及它被炮弹打到的时间标记出来,时间上限是初始能量值,因为超过了这个值就不能再走了,标记也就没意义。然后bfs搜的时候,用VIS[x][y][t]来判重,即当前点是否在第t秒以及走过了,我还加入了个曼哈顿距离来剪枝,如果当前点的剩余能量小于到终点的曼哈顿距离,那么就剪掉。

注意,更新x和y的时候,不必考虑向西和向北,因为终点是在东南方,刚开始我不确定这样对不对,但是去掉这两个点后依然能A,当然,也许是数据不够强,某个角落里还存在着一组诡异的数据,需要先绕回去几步,谁知道呢。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <queue>
  4 using    namespace    std;
  5
  6 const    int    SIZE = 105;
  7 const    int    UPDATE[][2] = {{1,0},{0,1},{0,0}};
  8 int    N,M,K,E;
  9 bool    FIRE[SIZE][SIZE][1005];
 10 bool    VIS[SIZE][SIZE][1005];
 11 bool    CASTLE[SIZE][SIZE];
 12 struct    Node
 13 {
 14     int    x,y,t,e;
 15     bool    check(void)
 16     {
 17         if(x < 0 || x > N || y < 0 || y > M || t > E || VIS[x][y][t] || CASTLE[x][y] ||
 18           FIRE[x][y][t] || !e || N - x + M - y > e)
 19             return    false;
 20         return    true;
 21     }
 22 };
 23 struct    Cas
 24 {
 25     char    ch;
 26     int    t,v,x,y;
 27 };
 28
 29 void    deal(char ch,int t,int v,int x,int y);
 30 void    bfs(void);
 31 int    main(void)
 32 {
 33     Cas    temp[105];
 34     while(scanf("%d%d%d%d",&N,&M,&K,&E) != EOF)
 35     {
 36         fill(&FIRE[0][0][0],&FIRE[SIZE - 1][SIZE - 1][1004],false);
 37         fill(&VIS[0][0][0],&VIS[SIZE - 1][SIZE - 1][1004],false);
 38         fill(&CASTLE[0][0],&CASTLE[SIZE - 1][SIZE - 1],false);
 39
 40         for(int i = 0;i < K;i ++)
 41         {
 42             scanf(" %c%d%d%d%d",&temp[i].ch,&temp[i].t,&temp[i].v,&temp[i].x,&temp[i].y);
 43             CASTLE[temp[i].x][temp[i].y] = true;
 44         }
 45         if(CASTLE[N][M])
 46         {
 47             puts("Bad luck!");
 48             continue;
 49         }
 50         for(int i = 0;i < K;i ++)
 51             deal(temp[i].ch,temp[i].t,temp[i].v,temp[i].x,temp[i].y);
 52         bfs();
 53     }
 54
 55     return    0;
 56 }
 57
 58 void    deal(char ch,int t,int v,int x,int y)
 59 {
 60     if(ch == ‘W‘)
 61     {
 62         int    stop = 0;
 63         for(int j = y - 1;j >= 0;j --)
 64             if(CASTLE[x][j])
 65             {
 66                 stop = j;
 67                 break;
 68             }
 69         for(int j = y - v,ini = 1;j >= stop;j -= v,ini ++)
 70             for(int k = ini;k <= E;k += t)
 71                 FIRE[x][j][k] = true;
 72
 73     }
 74     else    if(ch == ‘E‘)
 75     {
 76         int    stop = M;
 77         for(int j = y + 1;j <= M;j ++)
 78             if(CASTLE[x][j])
 79             {
 80                 stop = j;
 81                 break;
 82             }
 83
 84         for(int j = y + v,ini = 1;j <= stop;j += v,ini ++)
 85             for(int k = ini;k <= E;k += t)
 86                 FIRE[x][j][k] = true;
 87     }
 88     else    if(ch == ‘N‘)
 89     {
 90         int    stop = 0;
 91         for(int j = x - 1;j >= 0;j --)
 92             if(CASTLE[j][y])
 93             {
 94                 stop = j;
 95                 break;
 96             }
 97         for(int j = x - v,ini = 1;j >= stop;j -= v,ini ++)
 98             for(int k = ini;k <= E;k += t)
 99                 FIRE[j][y][k] = true;
100     }
101     else    if(ch == ‘S‘)
102     {
103         int    stop = N;
104         for(int j = x + 1;j <= N;j ++)
105             if(CASTLE[j][y])
106             {
107                 stop = j;
108                 break;
109             }
110         for(int j = x + v,ini = 1;j <= stop;j += v,ini ++)
111             for(int k = ini;k <= E;k += t)
112                 FIRE[j][y][k] = true;
113     }
114 }
115
116 void    bfs(void)
117 {
118     Node    first;
119     first.x = first.y = first.t = 0;
120     first.e = E;
121     queue<Node>    que;
122     que.push(first);
123     VIS[0][0][0] = true;
124
125     while(!que.empty())
126     {
127         Node    cur = que.front();
128         que.pop();
129
130         for(int i = 0;i < 3;i ++)
131         {
132             Node    next = cur;
133             next.x += UPDATE[i][0];
134             next.y += UPDATE[i][1];
135             next.t ++;
136             next.e --;
137             if(!next.check())
138                 continue;
139             if(next.x == N && next.y == M)
140             {
141                 printf("%d\n",next.t);
142                 return    ;
143             }
144             VIS[next.x][next.y][next.t] = true;
145             que.push(next);
146         }
147     }
148     puts("Bad luck!");
149 }
时间: 2025-01-02 18:36:19

HDU 3533 Escape (BFS + 预处理)的相关文章

【搜索】 HDU 3533 Escape BFS 预处理

要从0,0 点 跑到m,n点  路上会有k个堡垒发射子弹,有子弹的地方不能走,子弹打到别的堡垒就会消失,或者一直飞出边界(人不能经过堡垒 可以上下左右或者站着不动 每步都需要消耗能量  一共有eng个能量 先预处理出地图 用三维数组表示mp[x][y][time] time表示该时间的地图上储存不能走的点 然后就是普通BFS #include <stdio.h> #include <string.h> #include <stdlib.h> #include <s

HDU 3533 Escape BFS搜索

题意:懒得说了 分析:开个no[100][100][1000]的bool类型的数组就行了,没啥可说的 #include <iostream> #include <cstdio> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <cmath> #include <queue> #include

HDU 3533 Escape(BFS+预处理)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533 题目大意:给你一张n* m的地图,人在起点在(0,0)要到达终点(n,m)有k(k<=100)座炮台,每座炮台都有各自的发射方向.发射周期和发射速度,每隔一段时间会发射一定速度的炮弹,人每秒可以选择停在原地或者往上下左右走,问是否能在时间d之内安全到达终点.如果可以,请输出最短时间. 解题思路:BFS+预处理,分为以下几点: ①预处理,用step[x][y][t]记录(x,y)在时间t是否被炮

HDU 1733 Escape(分层网络流)

HDU 1733 Escape 题目链接 题意:给定一个图,#是墙,@是出口,.可以行走,X是人,每个时间每个格子只能站一个人,问最少需要多少时间能让人全部撤离(从出口出去) 思路:网络流,把每个结点每秒当成一个结点,这样枚举时间,每多一秒就在原来的网络上直接加一层继续增广即可,注意考虑方向的时候,要考虑上原地不动 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorit

HDU - 1428【bfs+记忆化】

点击查看详情--<IJCAI 2017 口碑商家客流量预测大赛> 漫步校园 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 4205    Accepted Submission(s): 1317 Problem Description LL最近沉迷于AC不能自拔,每天寝室.机房两点一线.由于长时间坐在电脑边,缺乏运动.他决定充分利用每

HDU 3605 Escape(最大流+缩点转换)

http://acm.hdu.edu.cn/showproblem.php?pid=3605 题目很简单,要求的就是最后能搬到星球上去的人的个数.刚开始看到,知道是最大流,就把人和星球都设为点,能生存就连线,权值为1,最后建立超级源点和超级汇点.求出最大流量即可.先是RE,开大数组后TLE.仔细算了,光光人到星球的便就可达到100w了,超时的概率太大了.后来找了解题报告,知道了缩点这一说,因为星球个数m最大只有10个,所以每个人最多只有1024种情况,把这每一种情况设为点(这里很抽象),将之与符

[ACM] hdu 1242 Rescue (BFS+优先队列)

Rescue Problem Description Angel was caught by the MOLIGPY! He was put in prison by Moligpy. The prison is described as a N * M (N, M <= 200) matrix. There are WALLs, ROADs, and GUARDs in the prison. Angel's friends want to save Angel. Their task is:

HDU 3605 Escape【二分图多重匹配】

题意: 有n个人去m个星球  告诉你每个人想去哪些星球和每个星球最多容纳多少人,问能不能让所有人都满足 分析: 二分图多重匹配 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 using namespace std; 6 7 const int maxn = 100005; 8 const int maxm = 15; 9 10

hdu 3605 Escape (二分图多重匹配)

Escape Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4298    Accepted Submission(s): 1129 Problem Description 2012 If this is the end of the world how to do? I do not know how. But now scient