zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    109         else
    110             puts("Bad luck!");
    111     }
    112     return 0;
    113 }
  • 相关阅读:
    试用solace 消息平台
    mqtt5 share subscription 简单说明
    文件批量重命名神器:Bulk Rename Utility
    Elasticsearch入门,这一篇就够了
    burp suite使用(一) --- 抓包,截包,改包
    BurpSuite安装和配置
    ORA-01779: 无法修改与非键值保存表对应的列”中涉及的概念和解决方法
    一个非常有用的函数——COALESCE
    ORA-01779: cannot modify a column which maps to a non-key-preserved table
    Oracle批量、大量Update方法总结
  • 原文地址:https://www.cnblogs.com/fu3638/p/7542682.html
Copyright © 2011-2022 走看看