Escape (BFS + 模拟)

简介: Problem Description The students of the HEU are maneuvering for their military training. The red army and the blue army are at war today.

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.

SampleInput

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

SampleOutput

9
Bad luck!

题意就是要你从(0,0)跑到(n,m),只能在d时间内跑到,并且在图中有k个炮台,炮台只能往一个方向(W,E,N,S)发送子弹,子弹发射间隔为t,速度为v。

人不能跑进炮台,炮台会挡住另一炮台的子弹,当且仅当人到达某个点且子弹也到达当点才算被射中,人可以不动。

题意清楚了就是BFS搜吧,但是同样标记数组得开一个三维数组标记坐标和时间,因为每个点可能不止走一次,所以这道题唯一的难度就是判断是否被射杀。其实不是很难,当你处于某个位置时,往四个方向找炮台判断是否会被杀死就行了。
代码:
 
  
  1 #include <iostream>
  2 #include <string>
  3 #include <cstdio>
  4 #include <cstdlib>
  5 #include <sstream>
  6 #include <iomanip>
  7 #include <map>
  8 #include <stack>
  9 #include <deque>
 10 #include <queue>
 11 #include <vector>
 12 #include <set>
 13 #include <list>
 14 #include <cstring>
 15 #include <cctype>
 16 #include <algorithm>
 17 #include <iterator>
 18 #include <cmath>
 19 #include <bitset>
 20 #include <ctime>
 21 #include <fstream>
 22 #include <limits.h>
 23 #include <numeric>
 24 
 25 using namespace std;
 26 
 27 #define F first
 28 #define S second
 29 #define mian main
 30 #define ture true
 31 
 32 #define MAXN 1000000+5
 33 #define MOD 1000000007
 34 #define PI (acos(-1.0))
 35 #define EPS 1e-6
 36 #define MMT(s) memset(s, 0, sizeof s)
 37 typedef unsigned long long ull;
 38 typedef long long ll;
 39 typedef double db;
 40 typedef long double ldb;
 41 typedef stringstream sstm;
 42 const int INF = 0x3f3f3f3f;
 43 
 44 int m,n,k,d;
 45 bool mp[110][110];
 46 bool vis[110][110][1010];
 47 
 48 int fx[5][2]={{1,0},{-1,0},{0,1},{0,-1},{0,0}};     //可以不动
 49 
 50 struct paotai{  //记录炮台数据
 51     char d;
 52     int t,v;
 53 }cas[110][110];
 54 
 55 struct node{
 56     int x,y;
 57     int step;
 58     node(int _x,int _y,int _step):x(_x),y(_y),step(_step){}
 59 };
 60 
 61 bool judge(int x,int y,int time){   //往四个方向找炮台
 62 
 63     for(int i = x-1; i >= 0; i--){
 64         if(mp[i][y]){
 65             if(cas[i][y].d == 'S' && time >= db(x-i) / cas[i][y].v){
 66                 double c = db(x-i) / cas[i][y].v;
 67                 if(time == c)
 68                     return false;
 69                 while(time >= c){
 70                     if(time == c)
 71                         return false;
 72                     c += cas[i][y].t;
 73                 }
 74             }
 75             break;  //只要找最近的就行了
 76         }
 77     }
 78 
 79     for(int i = x+1; i <= m; i++){
 80         if(mp[i][y]){
 81               if(cas[i][y].d == 'N' && time >= db(i-x) / cas[i][y].v){
 82                 double c = db(i-x) / cas[i][y].v;
 83                 if(time == c)
 84                     return false;
 85                 while(time >= c){
 86                     if(time == c)
 87                         return false;
 88                     c += cas[i][y].t;
 89                 }
 90             }
 91             break;
 92         }
 93     }
 94 
 95     for(int i = y-1; i >= 0; i--){
 96         if(mp[x][i]){
 97             if(cas[x][i].d == 'E' && time >= db(y-i) / cas[x][i].v){
 98                 double c = db(y-i) / cas[x][i].v;
 99                 if(time == c)
100                     return false;
101                 while(time >= c){
102                     if(time == c)
103                         return false;
104                     c += cas[x][i].t;
105                 }
106             }
107             break;
108         }
109     }
110 
111     for(int i = y+1; i <= n; i++){
112         if(mp[x][i]){
113             if(cas[x][i].d == 'W' && time >= db(i-y) / cas[x][i].v){
114                 double c = db(i-y) / cas[x][i].v;
115                 if(time == c)
116                     return false;
117                 while(time >= c){
118                     if(time == c)
119                         return false;
120                     c += cas[x][i].t;
121                 }
122             }
123             break;
124         }
125     }
126     return true;
127 }
128 
129 
130 bool check(int x,int y,int time){
131     if(x < 0 || x > m || y < 0 || y > n || time > d || mp[x][y]){
132         return false;
133     }
134     if(judge(x,y,time)){
135         return true;
136     }
137     return false;
138 }
139 
140 void bfs(){
141     MMT(vis);
142 
143     queue<node> s;
144     s.push(node(0,0,0));
145     vis[0][0][0] = 1;
146     while(!s.empty()){
147         node cnt = s.front();
148         s.pop();
149         if(cnt.step > d){
150             cout << "Bad luck!" << endl;
151             return ;
152         }
153         if(cnt.x == m && cnt.y == n && cnt.step <= d){
154             cout << cnt.step << endl;
155             return;
156         }
157         for(int i = 0; i < 5; i++){
158             int x = cnt.x + fx[i][0];
159             int y = cnt.y + fx[i][1];
160             int time = cnt.step + 1;
161             if(check(x,y,time) && !vis[x][y][time]){
162                 vis[x][y][time] = 1;
163                 s.push(node(x,y,time));
164             }
165         }
166     }
167     cout << "Bad luck!" << endl;
168 }
169 
170 int main(){
171     ios_base::sync_with_stdio(false);
172     cout.tie(0);
173     cin.tie(0);
174     char a;
175     int b,c,x,y;
176     while(cin>>m>>n>>k>>d){
177         MMT(mp);
178         for(int i = 0; i < k; i++){
179             cin>>a>>b>>c>>x>>y;
180             cas[x][y].d = a, cas[x][y].t = b,cas[x][y].v = c;
181             mp[x][y] = 1;
182         }
183         bfs();
184     }
185 }
 
  

 

 
 
目录
相关文章
|
6月前
|
并行计算 Go C++
2182.构造限制重复的字符串(模拟 贪心 优先队列 C++ Go)
【2月更文挑战第19天】2182.构造限制重复的字符串(模拟 贪心 优先队列 C++ Go)
50 1
|
算法 测试技术
库函数strstr的两种算法模拟实现(BF算法和kmp算法)
库函数strstr的两种算法模拟实现(BF算法和kmp算法)
|
6月前
|
测试技术 索引
【每日一题Day296】LC833字符串中的查找与替换 | 排序+模拟
【每日一题Day296】LC833字符串中的查找与替换 | 排序+模拟
44 0
|
6月前
|
前端开发
【每日一题Day228】LC2460对数组执行操作 | 模拟+双指针
【每日一题Day228】LC2460对数组执行操作 | 模拟+双指针
41 0
|
6月前
【每日一题Day151】LC1625执行操作后字典序最小的字符串 | BFS
【每日一题Day151】LC1625执行操作后字典序最小的字符串 | BFS
38 0
算法学习--KMP与Trie
算法学习--KMP与Trie
Shortest Path with Obstacle( CodeForces - 1547A )(模拟)
Shortest Path with Obstacle( CodeForces - 1547A )(模拟)
49 0
|
算法 Java 程序员
【手绘算法】力扣 3 无重复的最长字符串(Longest Substring Without Repeating Characters)
Hi,大家好,我是Tom。一个美术生转到Java开发的程序员。今天给大家分享的是力扣题第3题,无重复的最长字符串。在解题过程中,也会手写一些伪代码。当然,如果想要完整的源码的话,可以到我的个人主页简介中获取。 这道题呢属于中等难度,评估为四颗星,它的通过率只有39%。
91 0
|
数据建模
【每日一题Day66】LC1754构造字典序最大的合并字符串 | 贪心 双指针模拟
思路:双指针遍历两个字符串,贪心比较字符的字典顺序,并添加至结果集
76 0
【每日一题Day66】LC1754构造字典序最大的合并字符串 | 贪心 双指针模拟
|
机器学习/深度学习
【每日一题DAY24】LC1704判断字符串的两半是否相似|双指针 模拟
两个字符串 相似 的前提是它们都含有相同数目的元音('a','e','i','o','u','A','E','I','O','U')。注意,s 可能同时含有大写和小写字母。
75 0