您的位置:首页 > 编程语言

UVa11624大火蔓延的迷宫(代码觉得没问题,但是对答案是3有疑惑,而且没有在oj上验证)

2015-11-25 13:07 507 查看
你的任务是帮助Joe走出一个大火蔓延的迷宫。Joe每分钟可以走到上下左右4个方向的相邻格之一,而所有着火的格子都会往四周蔓延(即如果每个空格与着火格有公共边,则下一分钟这个空格将着火)。迷宫中有一些障碍格,Joe和火都无法进入。当Joe走到一个迷宫的边界格子时,我们认为他已经出了迷宫。

【输入格式】

输入第一行为数据组数T。每组数据第一行为两个整数R、C。以下R行每行有C个字符,及迷宫。其中“#”表示墙和障碍物,“.”表示空地,“J”是Joe的初始位置(也是一个空地),“F”是着火点。每组数据的迷宫中恰好有一个格子是“J”。

【输出格式】

对于每组数据,输出走出迷宫的最短时间(单位:分钟)。如果无法走出迷宫,则输出IMPOSSIBLE。

【分析】

如果没有火,那么本题是一个标准的迷宫问题,可以用BFS解决,加上了火,难度增加了多少呢?其实没多少。注意,火是不会自动熄灭的,因此只要某个格子在某时刻起火了,以后将一直如此。所以只需要预处理每个格子起火的时间,在BFS扩展结点的时候加上一个判断,当到达新结点时该格子没有火才真的把这个新结点加到队列中。

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 Specification

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.

Sample Input

2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F

Output Specification

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.

Output for Sample Input

3
IMPOSSIBLE


/*你的任务是帮助Joe走出一个大火蔓延的迷宫。Joe每分钟可以走到上下左右4个方向的相邻格之一,而所有着火的格子都会往四周蔓延(即如果每个空格与着火格有公共边,则下一分钟这个空格将着火)。
迷宫中有一些障碍格,Joe和火都无法进入。当Joe走到一个迷宫的边界格子时,我们认为他已经出了迷宫。

【输入格式】

输入第一行为数据组数T。每组数据第一行为两个整数R、C。以下R行每行有C个字符,及迷宫。其中“#”表示墙和障碍物,“.”表示空地,“J”是Joe的初始位置(也是一个空地),“F”是着火点。每组数据的迷宫中恰好有一个格子是“J”。

【输出格式】

对于每组数据,输出走出迷宫的最短时间(单位:分钟)。如果无法走出迷宫,则输出IMPOSSIBLE。*/

/*这道题对自己来说还是新鲜的,因为自己没有双重BFS的问题*/
/*标记出格子变成火的时间,然后人走的时候check下到这个格子的时候有没有变成火,如果没有,就可以往下走
对于input为什么第一个是3感到疑惑,不是2吗*/

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

#define MAXINT 1005

char map[MAXINT][MAXINT];
int visit[MAXINT][MAXINT];
int visitfire[MAXINT][MAXINT];
int fire[MAXINT][MAXINT];
int startx = 0;
int starty = 0;

int firex = 0;
int firey = 0;

int R = 0;
int C = 0;

int dir[4][2] = { { 1, 0 }, {-1, 0},{0, 1}, {0, -1} };

typedef struct fire
{
int x;
int y;
int time;
}fires;

fires qfire[MAXINT*MAXINT];

typedef struct person
{
int x;
int y;
int time;
}persons;

persons qperson[MAXINT*MAXINT];

void init()
{
int i = 0;
int j = 0;
int num = 0;
for (i = 0; i < MAXINT; i++)
{
for (j = 0; j < MAXINT; j++)
{
map[i][j]         = '\0';
visit[i][j]       = 0;
visitfire[i][j]   = 0;
fire[i][j]        = 0;
qfire[num].x      = 0;
qfire[num].y      = 0;
qfire[num].time   = 0;

qperson[num].x      = 0;
qperson[num].y      = 0;
qperson[num++].time = 0;
}
}
return;
}

//标记各个点什么时候变成火的,这样下一个bfsescape()会用到
void  bfsfire()
{
int front = 0;
int back  = 0;
int i = 0;
qfire[back].x = firex;
qfire[back].y = firey;
qfire[back++].time = 0;
while (front < back)
{
for (i = 0; i < 4; i++)
{
int x1 = qfire[front].x + dir[i][0];
int y1 = qfire[front].y + dir[i][1];
int tm = qfire[front].time +1;
if ((x1<0)||(x1>=R)||(y1<0)||(y1>=C)) continue;
if ('#' == map[x1][y1])continue;
if (1 == visitfire[x1][y1]) continue;
qfire[back].x      = x1;
qfire[back].y      = y1;
qfire[back++].time = tm;
fire[x1][y1]       = tm;
visitfire[x1][y1]  = 1;
}
front++;
}
return;
}

void  bfsescape()
{
int front = 0;
int back = 0;
int i = 0;
qperson[back].x      = startx;
qperson[back].y      = starty;
qperson[back++].time = 0;
while (front < back)
{
for (i = 0; i < 4; i++)
{
int x1 = qperson[front].x + dir[i][0];
int y1 = qperson[front].y + dir[i][1];
int tm = qperson[front].time + 1;

if ((0 == qperson[front].x) || ((R - 1) == qperson[front].x) || (0 == qperson[front].y) || ((C - 1) == qperson[front].y))
{
printf("%d\n", qperson[front].time+1);//这边+1才和答案一样,但不知道为什么				                                return;
}

if ((x1<0) || (x1 >= R) || (y1<0) || (y1 >= C)) continue;
if (('#' == map[x1][y1]) || ('F' == map[x1][y1])) continue;
if (1 == visit[x1][y1]) continue;
if (tm>=fire[x1][y1]) continue; //如果在人到达之前火就来了,那不能走
qperson[back].x      = x1;
qperson[back].y      = y1;
qperson[back++].time = tm;
visit[x1][y1]        = 1;
}
front++;
}
printf("IMPOSSIBLE\n");
return;
}

int main()
{
int i = 0;
int j = 0;
int k = 0;
int T = 0;
freopen("input.txt","r",stdin);
scanf("%d",&T);
for (i = 0; i < T;i++)
{
init();
scanf("%d %d",&R,&C);
for (j = 0; j < R;j++)
{
scanf("%s",&map[j]);
}
for (j = 0; j < R; j++)
{
for (k = 0; k < C; k++)
{
if ('F' == map[j][k])
{
firex = j;
firey = k;
}

if ('J' == map[j][k])
{
startx = j;
starty = k;
}
}
}
bfsfire();
bfsescape();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: