您的位置:首页 > 其它

[bfs] UVA11624-Fire!

2015-07-27 17:07 429 查看
11624 Fire!

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
IMPOSSIBLE


一个迷宫,其中有部分点着火了,火势上下左右四个方向每秒蔓延一个格子,并且每个点一旦着火不会熄灭。现在J在迷宫中的一个位置,问J是否能在火势把路封住以前逃到边界?如果可以输出逃出去的最短时间,如果不可以输出impossible。

好复杂的bfs,原来想对火和人做分别bfs,利用两个队列,一个存储人的状态,一个存储火的状态,但是这样修改以后整个状态不容易表示出来。

后来发现,火的扩散过程和人的行动两个过程是用相同的形式,所以可以用一个队列来存储两种状态,设置一个标志量判断是火还是人,先更新火的节点,再更新人的节点,按照顺序入队出队即可。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>

using namespace std;
const int MAXN = 1005;
int R,C,T;
int vis[MAXN][MAXN];
char mat[MAXN][MAXN];
int fx,fy;
int dx[]= {1,-1,0,0};
int dy[]= {0,0,1,-1};
struct node
{
int x,y;
int step;
bool isfire;
};

int bfs()
{
node a,next;
memset(vis,0,sizeof(vis));
queue<node> Q;
//"火"先进队列 注意:初始可能有多个位置起火。
for(int i = 0; i < R; i++)
{
for(int j = 0; j < C; j++)
{
if (mat[i][j] =='F')
{
a.x = i,a.y = j;
a.step = 0;
a.isfire = true;
Q.push(a);
}
}
}
//人再进队列.
next.x = fx,next.y =fy;
next.step = 0;
next.isfire = false;
Q.push(next);
while(!Q.empty())
{
a = Q.front();
Q.pop();
//        printf("fire? %d x:%d y:%d\n",a.isfire,a.x,a.y);
//        getchar();
if (a.isfire) //对火进行扩展
{
for(int i =0; i<4 ;i++)
{
int nx = a.x + dx[i];
int ny = a.y + dy[i];
// printf("nx : %d, ny:%d\n",nx,ny);
if (nx<0||nx>=R || ny<0 ||ny>=C ||
mat[nx][ny]=='#' ||mat[nx][ny]=='F' )
continue;
mat[nx][ny] ='F';
next.x = nx;
next.y = ny;
next.step = a.step+1;
next.isfire = true;
Q.push(next); //puts("push");
}
}
else //对人进行扩展
{
//  printf("x = %d, y = %d\n",a.x,a.y);
for(int i = 0;i<4;i++)
{
int nx = a.x+dx[i];
int ny = a.y+dy[i];
//   printf("    nx = %d, ny = %d\n",nx,ny);
if (nx<0 || nx>=R || ny<0 || ny >=C)
return a.step+1;
if (vis[nx][ny] || mat[nx][ny] =='#' || mat[nx][ny]=='F')
continue;
vis[nx][ny] = true;
next.x = nx;
next.y = ny;
next.isfire = false;
next.step = a.step+1;
Q.push(next);
}
}
}
return 0;
}

int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&R,&C);
fx = fy = -1;
for(int i =0;i<R;i++)
{
for(int j = 0;j<C;j++)
{
cin>>mat[i][j];
if (fx == -1 && mat[i][j] =='J')
fx = i,fy = j;
}
}

int ans = bfs();
if (ans) printf("%d\n",ans);
else printf("IMPOSSIBLE\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: