zoukankan      html  css  js  c++  java
  • UVA 11624 Fire!(两次BFS+记录最小着火时间)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671

    题目大意:一个n*m迷宫,迷宫中有一个点'J'是人也就是起点,有多个点'F'表示着火,人每秒都可以往水平或垂直方向走,火势也可以往水平或垂直方向蔓延,火和人都不能过'#',但可以过‘.’。问人最后能否从迷宫逃出,不被火烧到。

    解题思路:两次bfs,第一次求各点被火烧到的最小时间用step[x][y]记录,如果烧不到就是inf。第二次bfs,求从起点能否逃出迷宫,但是比如说下一步走到(x,y)时间是t,t如果>=step[x][y]则这个点不能走,因为走到这里时,这里已经备火势蔓延了。注意:有多个着火点,看了我两个小时。气死我了啊啊啊!!!

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<queue>
      4 using namespace std;
      5 const int N=1e3+5;
      6 const int inf=0x3f3f3f3f;
      7 
      8 struct node{
      9     int x,y,step;
     10 }pre,now;
     11 
     12 int m,n,ans,cnt,x1,y1;
     13 int d[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
     14 char map[N][N];
     15 int vis[N][N],step[N][N];//step[x][y]记录被各点烧到的最短时间 
     16 
     17 struct node2{
     18     int x,y;
     19 }point[N*N];
     20 
     21 //求着火时间 
     22 void bfs1(){
     23     queue<node>q;
     24     for(int i=1;i<=cnt;i++){
     25         int x=point[i].x;
     26         int y=point[i].y;
     27         now.x=x;
     28         now.y=y;
     29         now.step=0;
     30         step[x][y]=0;
     31         q.push(now);
     32     }
     33     while(!q.empty()){
     34         pre=q.front();
     35         q.pop();
     36         for(int i=0;i<4;i++){
     37             int xx=pre.x+d[i][0];
     38             int yy=pre.y+d[i][1];
     39             int t=pre.step+1;
     40             if(xx<1||yy<1||xx>n||yy>m||map[xx][yy]=='#'||step[xx][yy]!=inf)
     41                 continue;
     42             step[xx][yy]=t;
     43             now.x=xx;
     44             now.y=yy;
     45             now.step=t;    
     46             q.push(now);
     47         }
     48     }
     49 }
     50 //求是否能逃出去 
     51 bool bfs2(){
     52     queue<node>q;
     53     now.x=x1;
     54     now.y=y1;
     55     now.step=0;
     56     q.push(now);
     57     while(!q.empty()){
     58         pre=q.front();
     59         q.pop();
     60         for(int i=0;i<4;i++){
     61             int xx=pre.x+d[i][0];
     62             int yy=pre.y+d[i][1];
     63             int t=pre.step+1;
     64             if(t>=step[xx][yy]||map[xx][yy]=='#'||vis[xx][yy])
     65                 continue;
     66             if(xx<1||yy<1||xx>n||yy>m){
     67                 ans=t;
     68                 return true;
     69             }
     70             vis[xx][yy]=1;
     71             now.x=xx;
     72             now.y=yy;
     73             now.step=t;
     74             q.push(now);
     75         }
     76     }
     77     return false;
     78 }
     79 
     80 int main(){
     81     int T;
     82     scanf("%d",&T);
     83     while(T--){
     84         cnt=0;
     85         memset(vis,0,sizeof(vis));
     86         memset(step,0x3f,sizeof(step));
     87         memset(map,'.',sizeof(map));
     88         scanf("%d%d",&n,&m);    
     89         for(int i=1;i<=n;i++){
     90             getchar();
     91             for(int j=1;j<=m;j++){
     92                 scanf("%c",&map[i][j]);
     93                 if(map[i][j]=='F'){
     94                     point[++cnt].x=i;
     95                     point[cnt].y=j;
     96                 }
     97                 if(map[i][j]=='J')
     98                     x1=i,y1=j;
     99             }
    100         }
    101         bfs1();
    102         if(!bfs2())
    103             puts("IMPOSSIBLE");
    104         else
    105             printf("%d
    ",ans);
    106     }
    107     return 0;
    108 }
  • 相关阅读:
    sizeof
    p与p->next
    每天学点java_Date类使用
    每天学点java_修饰符
    每天学点java_UML类图
    每天学点java_Arrays类
    每天学点java_插入排序
    每天学点java_for循环
    每天学点java_选择排序
    centos7 mysql
  • 原文地址:https://www.cnblogs.com/fu3638/p/7527623.html
Copyright © 2011-2022 走看看