UVA11624 Fire!

来源:互联网 发布:ubuntu tensorflow安装 编辑:程序博客网 时间:2024/06/04 18:53

UVA11624 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.

这里写图片描述

大致题意
你被困在一个迷宫里,迷宫有多个起火点,然后每个单位时间火都会向上下左右四个方向扩散,墙的地方火不能烧着,你每个单位时间内可以移动一步,问你是否可以在被火烧到前从迷宫的任何一个边界跑出去。
注意(有多个起火点)

思路
bfs。 本来我是想用两个bfs,先将每个点的着火时间求出,然后求人到某点的时间,判断是否比起火的时间迟,如果能到边界就输出结果,然后不出所料就超时了。。。重新考虑一下,将这两个放在一起进行bfs,着火一次,走一次。

代码如下

#include <iostream> #include <cstdio>#include <cstdlib>#include <fstream>#include <algorithm>#include <climits>#include <cstring>#include <string>#include <set>#include <queue>#include <stack>#include <vector>#include <list>#include<sstream>#include<ctime>#define max  0x3fffffffusing namespace std;int dix[4]={0,1,0,-1};int diy[4]={1,0,-1,0};int m,n,xj,yj,flag;    char map[1005][1005]; struct node{    int x,y;    int time;    int f;  // f为1是人,f为0是火灾 };queue<node> que; void bfs(){    int sum=1;    while(!que.empty())    que.pop();    node u;    for(int i=0;i<n;i++)    for(int j=0;j<m;j++)    {        if(map[i][j]=='F')  //将起火点入队        {            u.x=i;            u.y=j;            u.time=0;            u.f=0;             que.push(u);        }    }    u.f=1;    u.time=0;    u.x=xj;    u.y=yj;    que.push(u); //将人的位置入队    while(!que.empty())    {        if(sum==0) //如果队列中已经没有人的点,结束        return;        node u=que.front();        que.pop();        if(u.f==0)  //如果是起火点        {            for(int i=0;i<4;i++)            {            int tx=u.x+dix[i];            int ty=u.y+diy[i];            if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]=='.')//在边界内还未着火            {                map[tx][ty]='F'; //改变为着火                node v;                v.x=tx;                v.y=ty;                v.f=0;                que.push(v); //入队            }           }        }        else if(u.f==1) //如果是人        {            sum--;//队列中人的点减一           if(u.x==0||u.x==n-1||u.y==0||u.y==m-1) //如果已经走到边界,输出结果,结束           {            flag=1;            cout<<u.time+1<<endl;            return;           }           for(int i=0;i<4;i++)           {            int tx=u.x+dix[i];            int ty=u.y+diy[i];            if(tx>=0&&tx<n&&ty>=0&&ty<m&&map[tx][ty]=='.') //如果该点还未走过且未着火            {                    map[tx][ty]='#';// 标记为墙,因为这个点不会再走了,而且火从这个点烧起来也追不上人。                    node v;                    v.x=tx;                    v.y=ty;                    v.f=1;                    v.time=u.time+1;//用时加1,入队                    sum++;   //队列中人的点数量也加1                    que.push(v);            }           }        }    }} int main()  {      int T;    scanf("%d",&T);    while(T--)    {        scanf("%d %d",&n,&m);        for(int i=0;i<n;i++)        scanf("%s",map[i]);        for(int i=0;i<n;i++)        for(int j=0;j<m;j++)        if(map[i][j]=='J')  //找到人的起点坐标        {             xj=i;             yj=j;        }        flag=0;        bfs();        if(flag==0) //如果出不来        cout<<"IMPOSSIBLE\n";    }    return 0;}
0 0