HDU3533 Escape (搜索)

来源:互联网 发布:淘宝专业版一钻以上 编辑:程序博客网 时间:2024/06/03 22:56

Escape

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


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!

题解:
这道题的意思就是,你要从(0,0)走到(n,m)(题目的坐标系是反的,所以我输入就直接把n,m反过来了),然后有k个炮台,坐标x,y,以速度v,时间间隔t打炮。。
你当然不能被打中,也不能经过炮台的位置,你有d的时间,问你能不能走到(n,m)。

有几个要注意的地方:
1.人不能到达炮塔所在的坐标
2.炮塔会挡住子弹
3.人如果停在这个坐标,而子弹也刚好到这个坐标,人死了。。
4.人可以选择停止不动

这道题肯定是先预处理炮台的发射,对于每个位置,我们预处理出炮弹到达的时间,然后我们从起点bfs的时候到达一个点的时候,如果该点并且现在到达的时间有炮弹,那么就不行,时间超过了d也不行。

这道题是不需要优先队列的,不然反而会变慢,因为bfs本来就是按照一层一层的状态来搜索的。

#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<queue>#include<iostream>#include<queue>using namespace std;#define MP(x,y,z) make_pair((x),make_pair((y),(z)))#define pb push_backconst int maxn=102;const int inf=0x3f3f3f3f;struct note {    char ins[3];    int t,v,x,y;} G[maxn];bool isPd[maxn][maxn];int n,m,k,energy;char in[3];vector<int> PD[maxn][maxn];bool vi[maxn][maxn][maxn*10];int d[5][2]= {{-1,0},{1,0},{0,-1},{0,1},{0,0}};inline int GetDer(char *tc) {    if(tc[0]=='N')return 0;    if(tc[0]=='S')return 1;    if(tc[0]=='W')return 2;    if(tc[0]=='E')return 3;}inline bool OK(int x,int y) {    return (x>=0&&x<=n&&y>=0&&y<=m);}bool NoPD(int x,int y,int tx,int ty,int der) {    while(x<tx||y<ty)  {        x+=d[der][0],y+=d[der][1];        if(isPd[x][y])return false;    }    return true;}bool Life(int x,int y,int t) {    return (*(lower_bound(PD[x][y].begin(),PD[x][y].end(),t)))==t;}struct notes {    int t,en,posx,posy;    notes(int aa=0,int bb=0,int cc=0,int dd=0) {        t=aa,en=bb,posx=cc,posy=dd;    }};void WORK() {    queue<notes>que;//t energy pos    while(!que.empty()) {        que.pop();    }    memset(vi,false,sizeof(vi));    vi[0][0][0]=true;    que.push(notes(0,energy,0,0));    int x,y,nowt,nowenergy;    notes NOW;    while(!que.empty()) {        NOW=que.front();        que.pop();        nowt=NOW.t;        nowenergy=NOW.en;        x=NOW.posx,y=NOW.posy;        if(nowenergy<0)continue;        if(x==n&&y==m) {            printf("%d\n",nowt);            return;        }        if(nowenergy<=0)continue;        for(int i=0; i<5; ++i) {            int tx=x+d[i][0],ty=y+d[i][1];            if(OK(tx,ty)&&(!isPd[tx][ty])&&(!vi[tx][ty][nowt+1])                    &&(!Life(tx,ty,nowt+1))) {                vi[tx][ty][nowt+1]=true,que.push(notes(nowt+1,nowenergy-1,tx,ty));            }        }    }    printf("Bad luck!\n");}int main() {#ifdef tangge    freopen("3533.txt","r",stdin);#endif // tangge    while(~scanf("%d%d%d%d",&n,&m,&k,&energy)) {        for(int i=0; i<=n; ++i) {            for(int j=0; j<=m; ++j) {                PD[i][j].clear();            }        }        memset(isPd,false,sizeof(isPd));        for(int i=0; i<k; ++i) {            scanf("%s%d%d%d%d",G[i].ins,&G[i].t,&G[i].v,&G[i].x,&G[i].y);            isPd[G[i].x][G[i].y]=true;        }        for(int i=0; i<k; ++i) {            int t=G[i].t,v=G[i].v,x=G[i].x,y=G[i].y,der=GetDer(G[i].ins),nowt=0;            while(1) {                int J=0;                for(int j=1;; ++j) {                    int tx=j*v*d[der][0]+x,ty=j*v*d[der][1]+y;                    if(OK(tx,ty)&&NoPD(x,y,tx,ty,der)) {                        if(isPd[tx][ty])break;                        if(j+nowt>energy)break;                        J=1;                        PD[tx][ty].pb(j+nowt);                    } else break;                }                if(!J)break;                nowt+=t;            }        }        for(int i=0; i<=n; ++i) {            for(int j=0; j<=m; ++j) {                PD[i][j].pb(inf);                sort(PD[i][j].begin(),PD[i][j].end());            }        }        WORK();    }    return 0;}
1 0
原创粉丝点击