UVA

来源:互联网 发布:端到端qos网络设计 编辑:程序博客网 时间:2024/05/21 21:48

           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

24 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

3IMPOSSIBLE

/*  输入R*C的矩阵 '#'代表墙不可越过  'J'代表人Joe  ‘F’代表火把。  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.  这就是典型的bfs() 我们要dfs两遍 一个是火把的 一个是人的  火把dfs实现的目的是为了记录火把到达i j所花的时间dist[i][j],以及能否到达visited_fire[i][j];  是为了后面对人dfs()的时候 判断当前的路是否可以走 这里有个细节 其实也很容易想到…  如果火不到当前的地方或者到该地方所花的时间少于火到当前所花的时间 那么人就可以走到这里  人能否逃离的判断是看人能否走到边界。  把当前dist[ren.x][ren.y]=1 dist[huo.x][huo.y]=1;这样就可以直接满足输出的答案 不然还要答案+1;  思路清晰了就好做了0-0 坑点是火把可能不是唯一的。*/#include <cstdio>#include <cstring>#include <cmath>#include <iostream>#include <algorithm>#include <string>#include <cstdlib>#include <queue>using namespace std;const int maxn = 1010;char mp[maxn][maxn];bool visited_fire[maxn][maxn];bool visited_man[maxn][maxn];struct node{int x,y,step;   //定义J、F当前的x y 以及step} J,F;queue<node>Q,q;int ans=0;bool flag=false;int dir[4][2]= {1,0,-1,0,0,1,0,-1};int dist1[maxn][maxn];//记录火走的时间int dist2[maxn][maxn];//记录人走的时间int T,R,C;bool check1(node a)//判断是否满足在矩阵范围内,防止越界{    if(a.x>=0&&a.x<R&&a.y>=0&&a.y<C) return true;    return false;}void bfs1(){    while(!Q.empty())    {        node head=Q.front();        Q.pop();        for(int i=0; i<4; i++)        {            node next;            next.x=head.x+dir[i][0];            next.y=head.y+dir[i][1];            if(check1(next)&&!visited_fire[next.x][next.y]&&mp[next.x][next.y]!='#')            {                next.step=head.step+1;                visited_fire[next.x][next.y]=true;                dist1[next.x][next.y]=dist1[head.x][head.y]+1;                Q.push(next);            }        }    }    return;}bool check2(node a)//判断人是否在边界。{    if(a.x==0||a.x==R-1||a.y==0||a.y==C-1) return true;    return false;}void bfs2(node start){    dist2[start.x][start.y]=1;    q.push(start);    visited_man[start.x][start.y]=true;    while(!q.empty())    {        node head=q.front();        q.pop();        if(check2(head))//可能一开始就在边界了。        {            flag=1;            ans=dist2[head.x][head.y];            return ;        }        for(int i=0; i<4; i++)        {            node next;            next.x=head.x+dir[i][0];            next.y=head.y+dir[i][1];            //满足没有越界、不是墙、人没有走过、火没有走过、或者火走过了但是人到此地方花费的时间比火少。            if(check1(next)&&!visited_man[next.x][next.y]&&mp[next.x][next.y]!='#'&&(!visited_fire[next.x][next.y]||dist2[head.x][head.y]+1<dist1[next.x][next.y]))            {                dist2[next.x][next.y]=dist2[head.x][head.y]+1;                visited_man[next.x][next.y]=true;                q.push(next);                if(check2(next))                {                    flag=1;                    ans=dist2[next.x][next.y];                    return ;                }            }        }    }    return ;}void init()//初始化。{    memset(visited_fire,false,sizeof(visited_fire));    memset(visited_man,false,sizeof(visited_man));    memset(dist1,0,sizeof(dist1));    memset(dist2,0,sizeof(dist2));    while(!Q.empty()) Q.pop();    while(!q.empty()) q.pop();    ans=-1;    flag=0;}void debug()//- - 找bug专用…{    for(int i=0; i<R; i++)    {        for(int j=0; j<C; j++)        {            printf("%d",dist1[i][j]);        }        puts("");    }    for(int i=0; i<R; i++)    {        for(int j=0; j<C; j++)        {            printf("%d",dist2[i][j]);        }        puts("");    }}int main(void){    scanf("%d",&T);    while(T--)    {        init();        scanf("%d%d",&R,&C);        for(int i=0; i<R; i++)            scanf("%s",mp[i]);        for(int i=0; i<R; i++)        {            for(int j=0; j<C; j++)            {                if(mp[i][j]=='J')                {                    J.x=i;                    J.y=j;                    dist2[i][j]=1;                    J.step=0;                }                else if(mp[i][j]=='F')                {                    F.x=i;                    F.y=j;                    F.step=1;                    dist1[i][j]=1;                    Q.push(F);//可能有多个火把 这里要不停的入队。                    visited_fire[i][j]=true;                }            }        }        bfs1();//对火进行bfs        bfs2(J);//对人进行bfs        //debug();        if(flag) printf("%d\n",ans);        else printf("IMPOSSIBLE\n");    }    return 0;}



0 0