题目:
Joe works in a maze. Unfortunately, portions of the maze have caught on fire, and the owner of the maze neglected to create a fire escape plan. Help Joe escape the maze. Given Joe’s location in the maze and which squares of the maze are on fire, you must determine whether Joe can exit the maze before the fire reaches him, and how fast he can do it. Joe and the fire each move one square per minute, vertically or horizontally (not diagonally). The fire spreads all four directions from each square that is on fire. Joe may exit the maze from any square that borders the edge of the maze. Neither Joe nor the fire may enter a square that is occupied by a wall.
Input
The first line of input contains a single integer, the number of test cases to follow. The first 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 fire 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 fire 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
IMPOSSIBL
题目:
J要逃离着火的森林,J和火都只能往上下左右四个方向转移,J到达边界即可离开。求最小的逃离步数,不能的话输出IMPOSSIBL。不过值一提的是,题目要求着火的位置并不唯一(一是因为portions。此外,题目说的是,there will be exactly one J in each test case,但是并没有说F),需要特别注意一下。
思路:
两个bfs()处理即可,不过要先处理着火的函数,因为要提前算出火到达每个地方的时间(times[][]数组),这样才能让J在走的时候,有选择性。
注意:
1.前面已经提到,第一个要注意的地方就是着火点不唯一。
2.因为队列q定义的是全局变量,有T组数据,所以每次读入新的数据前都要清空一次。(vis[][]一样)
3.还有在看解析的时候,发现一种初始化结构体的函数。以后也可以尝试使用:
typedef struct node
{
int r;
int c;
int step;
node(int r1,int c1,int step1)
{
r=r1;
c=c1;
step=step1;
}
node(){}
}node;
//使用的时候,不用定义一个结构体,三个变量即可,如下:
int R,C,STEP;
for(i=0;i<4;i++)
{
R=temp.r+dr[i];
C=temp.c+dc[i];
STEP=temp.step+1;
if(R>=0&&R<r&&C>=0&&C<c&&(Map[R][C]=='.'||Map[R][C]=='J')&&visit[R][C]==0)
{
visit[R][C]=1;
q.push(node(R,C,STEP));//传入这三个整数即可,和新定义一个结构体一样的意思。
times[R][C]=STEP;
}
}
#include<bits/stdc++.h>
#define MAX 1100
#define INF 0x3f3f3f3f
using namespace std;
typedef struct node
{
int x;
int y;
int step;
}node;
node ss,tt,s,w;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
char cc[MAX][MAX];
int vis[MAX][MAX];
int times[MAX][MAX];
int t,r,c;
int numstep;
queue<node> q;
void bfs_f()
{
while(!q.empty())
{
node first;
first=q.front();
q.pop();
for(int i=0;i<4;i++)
{
s.x=first.x+dir[i][0];
s.y=first.y+dir[i][1];
s.step=first.step+1;
if(s.x>=0&&s.x<r&&s.y>=0&&s.y<c&&(cc[s.x][s.y]=='.'||cc[s.x][s.y]=='J')&&!vis[s.x][s.y])
{
vis[s.x][s.y]=1;
q.push(s);
times[s.x][s.y]=s.step;
}
}
}
}
int bfs_j()
{
// cout<<"yes,it comes in----bfs_j()!"<<endl;
q.push(ss);
vis[ss.x][ss.y]=1;
while(!q.empty())
{
node second;
second=q.front();
q.pop();
if(second.x==0||second.x==r-1||second.y==0||second.y==c-1)
{
//cout<<"yes,it comes in------if()"<<endl;
numstep=second.step+1;
return 1;
}
for(int i=0;i<4;i++)
{
w.x=second.x+dir[i][0];
w.y=second.y+dir[i][1];
w.step=second.step+1;
if(w.x>=0&&w.x<r&&w.y>=0&&w.y<c&&cc[w.x][w.y]=='.'&&vis[w.x][w.y]==0&&w.step<times[w.x][w.y])
{
vis[w.x][w.y]=1;
q.push(w);
}
}
}
return 0;
}
int main()
{
cin>>t;
while(t--)
{
while(!q.empty())//每次进来,队列都得清空一次,因为会有多组数据,而队列定义的是全局的变量
{
q.pop();
}
cin>>r>>c;
for(int i=0;i<r;i++)
{
scanf("%s",&cc[i]);
for(int j=0;j<c;j++)
{
if(cc[i][j]=='J')
{
ss.x=i;
ss.y=j;
ss.step=0;
}
if(cc[i][j]=='F')//这里应该注意,因为起火的位置不唯一 。为什么呢(一是因为portions。此外,题目说的是,there will be exactly one J in each test case,但是并没有说F)
{
tt.x=i;
tt.y=j;
tt.step=0;
q.push(tt);
vis[i][j]=1;
times[i][j]=0;
}
}
}
for(int i=0;i<r;i++)
{
for(int j=0;j<c;j++)
{
times[i][j]=INF;
}
}
memset(vis,0,sizeof(vis));
bfs_f();
memset(vis,0,sizeof(vis));
if(bfs_j())
{
cout<<numstep<<endl;
}
else
cout<<"IMPOSSIBLE"<<endl;
}
return 0;
}