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 }