----- UVA 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
題目大意:
Joe被困在一個着火的迷宮裏,火源可以向上下左右四個方向同時蔓延(不一定只有一個火源),Joe可以逃向上下左右的某一個方向,火移動一個方格花一分鐘,人每移動一個方格花一分鐘,問你Joe是否可以逃出迷宮(任何一個邊界都可以看成出口),若可以則輸出所花費的最小時間,若不行則輸出”IMPOSSIBLE”.

解題思路:
兩次bfs,bfs1用來計算火蔓延到某個方格時的時間(time1[i][j]代表火蔓延到i,j位置時候的時間),bfs2則用來計算人到達某個地方時的時間(time2[i][j]代表人逃到i,j位置時候的時間),人能不能逃到i,j方格(1.若該方格火勢不會蔓延到(time1[i][j]==-1);2.火勢會蔓延到該方格,但是人要比火先到達,即(time2[i][j]>time[i][j];)

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
using namespace std;

int n,m;
char map[1010][1010];
int time1[1010][1010],time2[1010][1010];///time1[i]代表火勢蔓延到i點的時候的時間,time2[i]代表人逃到i點的時候的時間
int dri[4][2]= {{1,0},{0,1},{-1,0},{0,-1}};
queue<pair<int,int> >que;

void bfs1()
{
    memset(time1,-1,sizeof(time1));
    while(!que.empty()) que.pop();
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            if(map[i][j]=='F')
            {
                time1[i][j]=0;///火源位置處的時間都爲0
                que.push(make_pair(i,j));///將火源的座標加入隊列
            }
    while(!que.empty())///隊列非空的時候
    {
        pair<int,int> tmp=que.front();///取出隊首元素
        que.pop();
        int x=tmp.first;///將x賦值爲tmp中的第一個元素
        int y=tmp.second;///將y賦值爲tmp中的第二個元素
        for(int k=0; k<4; k++) ///四個方向
        {
            int dx=x+dri[k][0];
            int dy=y+dri[k][1];
            if(dx<0||dy<0||dx>=n||dy>=m) continue;///出界
            if(map[dx][dy]=='#'||time1[dx][dy]!=-1) continue;///牆或者是該點之前火勢已經蔓延過了
            que.push(make_pair(dx,dy));///將新的點的座標加入隊列中
            time1[dx][dy]=time1[x][y]+1;///到達該點的時間爲上一步加一
        }
    }
}

int bfs2()
{
    memset(time2,-1,sizeof(time2));
    while(!que.empty()) que.pop();
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            if(map[i][j]=='J')
            {
                time2[i][j]=0;///Joe的起始位置的時間爲0
                que.push(make_pair(i,j));///將Joe的起始座標加入隊列
            }
    while(!que.empty())
    {
        pair<int,int> tmp=que.front();///取出隊首元素
        que.pop();
        int x=tmp.first;
        int y=tmp.second;
        if(x==0||y==0||x==n-1||y==m-1) return time2[x][y]+1;///已經到達的四個邊界中的某一個
        for(int k=0; k<4; k++)
        {
            int dx=x+dri[k][0];
            int dy=y+dri[k][1];
            if(dx<0||dy<0||dx>=n||dy>=m) continue;///出界
            if(map[dx][dy]=='#'|| time2[dx][dy]!=-1) continue;///牆或者已經被走過了
            if(time1[dx][dy]!=-1&&time2[x][y]+1>=time1[dx][dy]) continue;///這一點火勢一定會蔓延到,並且人比火勢後到達,或者兩者同時到達
            que.push(make_pair(dx,dy));
            time2[dx][dy]=time2[x][y]+1;
        }
    }
    return -1;
}

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]);
            bfs1();
            int ans=bfs2();
            if(ans==-1) printf("IMPOSSIBLE\n");
            else printf("%d\n",ans);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章