Fire!

Joe works in a maze. Unfortunately, portions of the maze have
caught on re, and the owner of the maze neglected to create a re
escape plan. Help Joe escape the maze.
Given Joe's location in the maze and which squares of the maze
are on re, you must determine whether Joe can exit the maze before
the re reaches him, and how fast he can do it.
Joe and the re each move one square per minute, vertically or
horizontally (not diagonally). The re spreads all four directions
from each square that is on re. Joe may exit the maze from any
square that borders the edge of the maze. Neither Joe nor the re
may enter a square that is occupied by a wall.
Input
The rst line of input contains a single integer, the number of test
cases to follow. The rst line of each test case contains the two
integers R and C, separated by spaces, with 1  R;C  1000. The
following R lines of the test case each contain one row of the maze. Each of these lines contains exactly
C characters, and each of these characters is one of:
 #, a wall
 ., a passable square
 J, Joe's initial position in the maze, which is a passable square
 F, a square that is on re
There will be exactly one J in each test case.
Output
For each test case, output a single line containing `IMPOSSIBLE' if Joe cannot exit the maze before the
re reaches him, or an integer giving the earliest time Joe can safely exit the maze, in minutes.
Sample Input
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
Sample Output
3
IMPOSSIBLE

题目大意:Joe在一个迷宫里工作,然后迷宫着火了,火扩散的速度和Joe移动的速度一样都是每分钟一格,'#'代表着墙,而Joe和火都只能走'.'所代表的广场,问Joe能否在火烧到他之前逃出迷宫。

思路两次bfs:将火蔓延的时间进行预处理,用一次BFS搜索出火到达每一个广场所需要的最短时间,然后再BFS人到各个广场所需要的时间,如果人到某一个地点的时间少于火到达这里的这时间,或者人到达的某一个地点,火烧不到,就可以继续搜索,直到Joe到矩阵的边界为止

  1 //
  2 // Created by w on 2020/11/13.
  3 //
  4 
  5 #include<iostream>
  6 #include<cstdio>
  7 #include<queue>
  8 #include<cstring>
  9 using namespace std;
 10 const int maxn=1010;
 11 const int inf=0x3f3f3f3f;
 12 typedef pair<int,int> P;
 13 int sx,sy,cnt,R,C,T,final;
 14 int s[maxn][maxn];
 15 int judge[maxn][maxn];
 16 char map[maxn][maxn];
 17 int dx[]={0,1,-1,0};
 18 int dy[]={1,0,0,-1};
 19 
 20 bool judgein1(int nx,int ny)
 21 {
 22     if(nx>=0&&ny>=0&&ny<C&&nx<R&&map[nx][ny]=='.'&&s[nx][ny]==inf)
 23         return true;
 24     return false;
 25 }
 26 bool judgein2(int nx,int ny)
 27 {
 28     if(nx>=0 && ny>=0 && ny<C &&nx<R&&map[nx][ny]!='#'&&judge[nx][ny]==inf)
 29         return true;
 30     return false;
 31 }
 32 void Joe_bfs()
 33 {
 34     queue<P >que;
 35     que.push(P(sx,sy));//存放初始位置坐标pair(sx,sy)
 36     s[sx][sy]=0;
 37     while(que.size())
 38     {
 39         P p=que.front();
 40         que.pop();
 41         for(int i=0;i<4;i++)//遍历各个方向
 42         {
 43             int nx=p.first+dx[i];
 44             int ny=p.second+dy[i];
 45             if(judgein1(nx,ny))
 46             {
 47                 que.push(P(nx,ny));
 48                 s[nx][ny]=s[p.first][p.second]+1;//记录火燃烧的时间,用每一个新的坐标存放时间
 49             }
 50         }
 51     }
 52 }
 53 void Fire_bfs()
 54 {
 55     memset(judge,inf,sizeof(judge));//重新初始化judge数组
 56     queue<P>que;
 57     for(int i=0;i<R;i++)
 58     {
 59         for(int j=0;j<C;j++)
 60         {
 61             if(map[i][j]=='F')
 62             {
 63                 que.push(P(i,j));//入队
 64                 judge[i][j]=0;//标记火的位置
 65             }
 66         }
 67     }
 68     while(que.size())
 69     {
 70         P p=que.front();
 71         que.pop();
 72         for(int i=0;i<4;i++)
 73         {
 74             int nx=p.first+dx[i];
 75             int ny=p.second+dy[i];
 76             if(judgein2(nx,ny))
 77             {
 78                 judge[nx][ny]=judge[p.first][p.second]+1;//记录时间
 79                 if(judge[nx][ny]<=s[nx][ny])//如果被火烧到了,此位置设为-1
 80                     s[nx][ny]=-1;
 81                 que.push(P(nx,ny));
 82             }
 83         }
 84     }
 85 }
 86 int main()
 87 {
 88     ios::sync_with_stdio(false);
 89     cin>>T;
 90     while(T--)
 91     {
 92         final=inf;//初始化
 93         memset(s,inf,sizeof(s));
 94         memset(map,0,sizeof(map));
 95         cnt=0;
 96         cin>>R>>C;
 97         for(int i=0;i<R;i++)
 98         {
 99             for(int j=0;j<C;j++)
100             {
101                 cin>>map[i][j];
102                 if(map[i][j]=='J')//记录初始位置
103                 {
104                     sx=i;
105                     sy=j;
106                 }
107             }
108         }
109         Joe_bfs();
110         Fire_bfs();
111         for(int i=0;i<R;i++)
112         {
113             for(int j=0;j<C;j++)
114             {
115                 if(i==R-1||j==C-1||i==0||j==0)
116                     if(s[i][j]!=-1&&s[i][j]!=inf)//这个点如果没有被火烧到或者没有对
117                     final=min(final,s[i][j]);
118             }
119         }
120         if(final!=inf)
121             cout<<final+1<<endl;
122         else
123             cout<<"IMPOSSIBLE"<<endl;
124     }
125     return 0;
126 }

 

posted @ 2020-11-13 22:21  BlackSnow  阅读(101)  评论(0)    收藏  举报