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’为 Joe的起始位置,'F’为火的起始位置(可能不止一处)。
joe和火都能从四个方向走,问走出迷宫最短时间
思路:
两次BFS,目的分别求出Joe和火到达任意一点的时间,
(火的时间不再存放在和横纵坐标同一结构体中,而是在以更直观的数组中(即下面代码的fire数组),目的是为了之后更方便的与Joe到达该点的时间作比较)
#include <stdio.h>
#include <string.h>
#define INF 0x3f3f3f
int n, m;
struct node
{
int x, y;
} str[1000005], p, q;
int t[4][2] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0} };
char a[1002][1002];
int fire[1002][1002];
int joe[1002][1002];
int judge(int x, int y)
{
if( x>=0&&x<n && y>=0&&y<m && a[x][y]!='#') return 1;
else return 0;
}
int judge_re(int x, int y)
{
if(x<0 || x>=n || y<0 || y>=m) return 1;
else return 0;
}
void bfs_fire()
{
int i, j, in, out;
in = out = 0;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
if(a[i][j]=='F')
{
p.x = i;
p.y = j;
fire[i][j] = 0;
str[in++] = p;
}
}
}
while(in>out)
{
p = str[out++];
for(i=0; i<4; i++)
{
q = p;
if( judge(q.x+t[i][0], q.y+t[i][1])
&&fire[q.x][q.y]+1<fire[q.x+t[i][0]][q.y+t[i][1]] )
{
q.x += t[i][0];
q.y += t[i][1];
str[in++] = q;
fire[q.x][q.y] = fire[p.x][p.y]+1;
}
}
}
}
void bfs_joe(int sx, int sy)
{
int i, in, out;
in = out = 0;
p.x = sx;
p.y = sy;
joe[sx][sy] = 0;
str[in++] = p;
while(in>out)
{
p = str[out++];
for(i=0; i<4; i++)
{
q = p;
if(judge_re(q.x+t[i][0], q.y+t[i][1]))
{
printf("%d\n", joe[q.x][q.y]+1);
return;
}
if( judge(q.x+t[i][0], q.y+t[i][1])
&& joe[q.x][q.y]+1 < fire[q.x+t[i][0]][q.y+t[i][1]]
&& joe[q.x][q.y]+1 < joe[q.x+t[i][0]][q.y+t[i][1]])
{
q.x += t[i][0];
q.y += t[i][1];
str[in++] = q;
joe[q.x][q.y] = joe[p.x][p.y] + 1;
}
}
}
printf("IMPOSSIBLE\n");
}
int main()
{
int t, i, j, sx, sy;
scanf("%d", &t);
while(t--)
{
scanf("%d %d", &n, &m);
for(i=0; i<n; i++)
{
getchar();
for(j=0; j<m; j++)
{
scanf("%c", &a[i][j]);
if(a[i][j]=='J')
{
sx = i;
sy = j;
}
}
}
memset(fire, INF, sizeof(fire));
memset(joe, INF, sizeof(joe));
bfs_fire();
bfs_joe(sx, sy);
}
return 0;
}
题外话:
做这道题的时候犯了一个低级的错误,明明n,m已经定义成了全局变量,但在主函数里又定义了一次,导致BFS的时候n,m值错了,运行没报错,有一段时间才找出来。