HDU 3533 Escape

题目描述:

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!

解题报告:

1:仔细阅读题目,可以得知这些条件:炮台会阻挡炮弹,人不能经过炮台,人可以不动(站在原地等待),不动也会扣能量值,能量耗尽即死亡,行进途中不会被攻击。

2:二维数组无法标记,因为可以站在原地等待,还要加一维时间来标记。但不能用int,好像会ME。也可能是我写搓了=.=。可以bool数组,节省空间。

3:这题主要是init函数最关键,这个函数写完这题就做完了。这里也是借鉴了大佬的代码。前面两个循环很容易理解,一个跑炮台个数,一个跑周期。其中变量s所在的循环遍历的路程。因为行进途中不会被攻击,只有取模为0时,才开始标记。

4:下面举个例子,是怎样标记的。比如这个炮台样例:N 3 2 1 1。N代码向上射击,稍微手推就知道这些状态不能走:(1+2x, 1, 0+3t)其中两个变量在变。其他情况类似。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N1 = 100+10;
const ll N2 = 1000+10;
bool CaPos[N1][N1], visit[N1][N1][N2], visit1[N1][N1][N2];
int dir[5][2] = {0, 0, 1, 0, -1, 0, 0, 1, 0, -1};
struct ca{
    int dir, t, v, x, y;
}Ca[N1];
struct point{
    int x, y, step;
}p1, p2;
queue<point> Q;
inline void init(ll m, ll n, ll k, ll d){
    memset(visit, 0, sizeof(visit));
    for(int i=0; i<k; ++i){
        for(int j=0; j<=d; j+=Ca[i].t){
            for(int s=1; ; ++s){
                int xx = Ca[i].x + dir[Ca[i].dir][0]*s;
                int yy = Ca[i].y + dir[Ca[i].dir][1]*s;
                if(xx < 0 || yy < 0 || xx > m || yy > n || CaPos[xx][yy])break;
                if(s % Ca[i].v == 0)visit[xx][yy][j+s/Ca[i].v] = 1;
            }
        }
    }
}
int bfs(int m, int n, int k, int d){
    while(!Q.empty())Q.pop();memset(visit1, 0, sizeof(visit1));
    p1.x = 0, p1.y = 0, p1.step = 0, visit1[0][0][0] = true;
    Q.push(p1);
    while(!Q.empty()){
        p1 = Q.front();
        if(p1.step >= d)return -1;
        if(p1.x == m && p1.y == n)return p1.step;
        for(int i=0; i<5; ++i){
            int xx = p1.x+dir[i][0];
            int yy = p1.y+dir[i][1];
            p2.step = p1.step+1;
            if(xx < 0 || yy < 0 || xx > m || yy > n || CaPos[xx][yy])continue;
            if(visit[xx][yy][p2.step] || visit1[xx][yy][p2.step])continue;
            p2.x = xx, p2.y = yy, visit1[xx][yy][p2.step] = 1;
            Q.push(p2);
        }
        Q.pop();
    }
    return -1;
}
int main(){
    int m, n, k, d;
    char c[2];
    while(~scanf("%d%d%d%d", &m, &n, &k, &d)){
        memset(CaPos, 0, sizeof(CaPos));
        for(int i=0; i<k; ++i){
            scanf("%s%d%d%d%d", c, &Ca[i].t, &Ca[i].v, &Ca[i].x, &Ca[i].y);
            if(c[0] == 'N')Ca[i].dir = 2;
            if(c[0] == 'S')Ca[i].dir = 1;
            if(c[0] == 'W')Ca[i].dir = 4;
            if(c[0] == 'E')Ca[i].dir = 3;
            CaPos[Ca[i].x][Ca[i].y] = 1;
        }
        init(m, n, k, d);
        int ans = bfs(m, n, k, d);
        if(ans == -1)puts("Bad luck!");
        else printf("%d\n", ans);
    }
    return 0;
}
发布了190 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/jun_____/article/details/104234275