HDU 3533 Escape(BFS+预处理)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 3533 Escape(BFS+预处理)相关的知识,希望对你有一定的参考价值。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3533
题目大意:给你一张n* m的地图,人在起点在(0,0)要到达终点(n,m)有k(k<=100)座炮台,每座炮台都有各自的发射方向、发射周期和发射速度,每隔一段时间会发射一定速度的炮弹,人每秒可以选择停在原地或者往上下左右走,问是否能在时间d之内安全到达终点。如果可以,请输出最短时间。
解题思路:BFS+预处理,分为以下几点:
①预处理,用step[x][y][t]记录(x,y)在时间t是否被炮弹打到,这样在bfs时直接判断step就可以了。要注意炮台是可以挡住子弹的(比如从(0,0)到(0,3)如果(0,2)有炮台那就会被挡住,开始没注意半路被炮台挡住,而是只管每秒发射到的点,GG。。。),还有炮台所在地也是不能走的,所以要不要边输入炮台信息边计算step,因为后面输入的炮台可能会档子弹的,输完再预处理。
②BFS,要用vis[x][y][t]表示(x,y)这个点在时间t已经走过了,判重,记得要判断(t>lim)是直接返回false,否则会出错(不一定,反正我的会)。
③数组记得用bool型,否则会超内存。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<queue> 5 #include<string> 6 using namespace std; 7 const int N=1e2+5; 8 9 int m,n,k,lim,ans; 10 int d[6][2]={{-1,0},{1,0},{0,-1},{0,1},{0,0}}; 11 bool attack[N][N][1005];//判断(x,y)在时间t是否被炮台攻击 12 bool vis[N][N][1005];//判断t时刻在(x,y) 的状态是否出现过,判重 13 14 struct node{ 15 int x,y,step; 16 }pre,now; 17 18 struct node1{ 19 int c,v,t,x,y; 20 }a[N]; 21 22 bool bfs(){ 23 queue<node>q; 24 now.x=0; 25 now.y=0; 26 now.step=0; 27 q.push(now); 28 while(!q.empty()){ 29 pre=q.front(); 30 q.pop(); 31 for(int i=0;i<5;i++){ 32 int xx=pre.x+d[i][0]; 33 int yy=pre.y+d[i][1]; 34 int t=pre.step+1; 35 //时间不能超过lim 36 if(t>lim) 37 continue; 38 if(xx<0||yy<0||xx>n||yy>m) 39 continue; 40 if(vis[xx][yy][t]||attack[xx][yy][t]||attack[xx][yy][0]) 41 continue; 42 if(xx==n&&yy==m){ 43 ans=t; 44 return true; 45 } 46 vis[xx][yy][t]=true; 47 now.x=xx; 48 now.y=yy; 49 now.step=t; 50 q.push(now); 51 } 52 } 53 return false; 54 } 55 56 int main(){ 57 while(~scanf("%d%d%d%d",&n,&m,&k,&lim)){ 58 memset(vis,false,sizeof(vis)); 59 memset(attack,false,sizeof(attack)); 60 for(int i=1;i<=k;i++){ 61 getchar(); 62 scanf("%c%d%d%d%d",&a[i].c,&a[i].t,&a[i].v,&a[i].x,&a[i].y); 63 //表示这个位置有炮台 64 attack[a[i].x][a[i].y][0]=true; 65 } 66 67 for(int i=1;i<=k;i++){ 68 char c; 69 int t,v,x,y; 70 c=a[i].c,t=a[i].t,v=a[i].v,x=a[i].x,y=a[i].y; 71 int idx; 72 if(c==‘N‘) 73 idx=0; 74 if(c==‘S‘) 75 idx=1; 76 if(c==‘W‘) 77 idx=2; 78 if(c==‘E‘) 79 idx=3; 80 int tmp=1; 81 while(1){ 82 int xx=x+d[idx][0]*v*tmp; 83 int yy=y+d[idx][1]*v*tmp; 84 if(xx<0||yy<0||xx>n||yy>m) 85 break; 86 bool flag=false; 87 //判断中途是否有炮台挡住子弹 88 for(int j=1+v*(tmp-1);j<=v*tmp;j++){ 89 int tx=x+d[idx][0]*j; 90 int ty=y+d[idx][1]*j; 91 if(attack[tx][ty][0]){ 92 flag=true; 93 break; 94 } 95 } 96 if(flag) 97 break; 98 //根据周期,计算被子弹攻击的时间 99 int tt=tmp; 100 while(tt<=1000){ 101 attack[xx][yy][tt]=true; 102 tt+=t; 103 } 104 tmp++; 105 } 106 } 107 if(bfs()) 108 printf("%d\n",ans); 109 else 110 puts("Bad luck!"); 111 } 112 return 0; 113 }
以上是关于HDU 3533 Escape(BFS+预处理)的主要内容,如果未能解决你的问题,请参考以下文章