Fork me on GitHub

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. 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 }

 


posted @ 2018-07-31 20:29  Xenny  阅读(379)  评论(0编辑  收藏  举报