HDU 3533Escape (bfs)

Posted fang-hao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3533Escape (bfs)相关的知识,希望对你有一定的参考价值。

传送门

题目描述

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. 

 

题目翻译

现在要从(0,0)点向(m,n)走,每秒可以向上,下,左,右走一步,或者待在原地,每过一秒他的生命就要-   1s,现在地图上有一些炮台,会向某一个方向发射炮弹。每个炮台隔一段时间发射一次,且子弹速度已知,如果某一秒人在一个地方且一个子弹也刚好到达哪儿,那么他就死了,并且子弹不会撞到子弹,炮台会挡住子弹,那么现在这个人能否在生命减完前到达呢?如果可以,输出最小的时间。

 

解题思路

这道题看下数据范围,地图100*100,时间最多100,那就暴力呗。从(0,0)开始宽搜,每到一个点判断能不能在这个时间到达,用vis[i][j][k]表示第k秒停留在(i,j)这个点,每次判断就像四个方向看一下有没有指向这里的炮台,计算出第一枚炮弹到这里的时间,那么每t秒就会来一发炮弹,用k减去第一发炮弹的时间,看能不能整除t就可以了。

 

代码

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 #define N 1
  7 #define S 2
  8 #define E 3
  9 #define W 4
 10 using namespace std;
 11 int nx[]={1,0,-1,0,0};
 12 int ny[]={0,1,0,-1,0};
 13 int m,n,k,d;
 14 struct nod{
 15     int x,y,step;
 16 };
 17 struct nod1{
 18     int dir,t,v;
 19 };
 20 nod1 cast[150][150];
 21 bool vis[150][150][150];
 22 queue<nod>q;
 23 inline void read(int &x){
 24     x=0; register char ch=getchar();
 25     while(ch<0||ch>9)ch=getchar();
 26     while(ch>=0&&ch<=9)x=x*10+ch-0,ch=getchar();
 27 }
 28 inline void ini(){
 29     while(!q.empty())q.pop();
 30     memset(cast,0,sizeof(cast));
 31     memset(vis,0,sizeof(vis));
 32 }
 33 inline bool check(int x,int y,int t){
 34     if(cast[x][y].v)return 0;
 35     for(register int i=x-1;i>=0;i--){
 36         if(!cast[i][y].dir)continue;
 37         if(cast[i][y].dir==S){
 38             int f=(x-i)/cast[i][y].v;
 39             if(f*cast[i][y].v!=x-i)break;
 40             else if((t-f)/cast[i][y].t*cast[i][y].t==t-f)return 0;
 41             break;
 42         }
 43         else break;
 44     }
 45     for(register int i=x+1;i<=m;i++){
 46         if(!cast[i][y].dir)continue;
 47         if(cast[i][y].dir==N){
 48             int f=(i-x)/cast[i][y].v;
 49             if(f*cast[i][y].v!=i-x)break;
 50             else if((t-f)/cast[i][y].t*cast[i][y].t==t-f)return 0;
 51             break;
 52         }
 53         else break;
 54     }
 55     for(register int i=y-1;i>=0;i--){
 56         if(!cast[x][i].dir)continue;
 57         if(cast[x][i].dir==E){
 58             int f=(y-i)/cast[x][i].v;
 59             if(f*cast[x][i].v!=y-i)break;
 60             else if((t-f)/cast[x][i].t*cast[x][i].t==t-f)return 0;
 61             break;
 62         }
 63         else break;
 64     }
 65     for(register int i=y+1;i<=n;i++){
 66         if(!cast[x][i].dir)continue;
 67         if(cast[x][i].dir==W){
 68             int f=(i-y)/cast[x][i].v;
 69             if(f*cast[x][i].v!=i-y)break;
 70             else if((t-f)/cast[x][i].t*cast[x][i].t==t-f)return 0;
 71             break;
 72         }
 73         else break;
 74     }
 75     return 1;
 76 }
 77 int main(){
 78     while(~scanf("%d%d%d%d",&m,&n,&k,&d)){
 79         ini();
 80         register int t,v,x,y;
 81         register char di[10];
 82         for(register int i=1;i<=k;i++){
 83             scanf("%s",di),read(t),read(v),read(x),read(y);
 84             if(di[0]==N)cast[x][y].dir=N;
 85             else if(di[0]==S)cast[x][y].dir=S;
 86             else if(di[0]==E)cast[x][y].dir=E;
 87             else if(di[0]==W)cast[x][y].dir=W;
 88             cast[x][y].v=v,cast[x][y].t=t;
 89         }
 90         nod temp;
 91         temp.x=0,temp.y=0,temp.step=0,vis[0][0][0]=1;
 92         q.push(temp);
 93         int flag=0;
 94         while(!q.empty()){
 95             nod now=q.front(); q.pop();
 96             if(now.x==m&&now.y==n){
 97                 cout<<now.step<<endl;
 98                 flag=1;
 99                 break;
100             }
101             nod next=now;
102             next.step++;
103             if(next.step>d)continue;
104             for(register int i=0;i<=4;i++){
105                 next.x=now.x+nx[i],next.y=now.y+ny[i];
106                 if(next.x>=0&&next.x<=m&&next.y>=0&&next.y<=n){
107                     if(!vis[next.x][next.y][next.step]&&check(next.x,next.y,next.step)){
108                         q.push(next);
109                         vis[next.x][next.y][next.step]=1;
110                     }
111                 }
112             }
113         }
114         if(!flag)printf("Bad luck!
");
115     }
116 }

 

以上是关于HDU 3533Escape (bfs)的主要内容,如果未能解决你的问题,请参考以下文章

HDU-3533 Escape (BFS

HDU - 3533Escape(bfs)

HDU 3533 Escape(BFS+预处理)

搜索 HDU 3533 Escape BFS 预处理

hdu3533Escape(预处理+bfs)

HDU3533(Escape)