传送门

题目大意就是给1个n*m的网格,上面有的点能走,有的点不能走(墙),然后有的点是火源,火源和人一样,每次都是上下左右四个方向蔓延,速度一样是1,火也不可以从墙上跨过去,给你人的起点,终点是只要走到边界就行,就是走出矩阵,问你最小逃生时间。

这个题算是基本的广搜题吧!我们想下他跟我们见过的最最基本的广搜有什么区别?是不是就是多了几个火源,而火源的作用是什么,是不是就是在蔓延的时候把一些能走的点变成不能走了.所以我们可以先处理火源,把每个点最早到达的火源的时间记录下来,用所有的火源把地图处理完了之后再跑广搜。具体细节可以看代码。

题目中需要注意的地方:

  • 题目中没有保证单个火源
  • 多个输入样例注意清空队列(我就多次死在这上面)
  • 数组模拟队列要注意空间要开的够大,不然会报RE
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char mp[1010][1010];
int t[1010][1010],vis[1010][1010],step[1010][1010];
int mv[4][2] = {0,1,0,-1,1,0,-1,0};
int jx,jy,fx,fy,r,c;
typedef pair <int,int> P;
void bfsfire()
{
    P que[1010];
    memset(t,0,sizeof(t));
    int frt = 0,til = 0;
    que[til].first = fx;
    que[til++].second = fy;
    vis[fx][fy] = 1;
    while(frt < til)
    {
        P q = que[frt];
        int next_x,next_y;
        for(int i = 0;i < 4; i++)
        {
            next_x = q.first + mv[i][0];
            next_y = q.second + mv[i][1];
            if(next_x >= 0 && next_x < r && next_y >= 0 && next_y < c && mp[next_x][next_y] != '#' && !vis[next_x][next_y])
            {
                que[til].first = next_x;
                que[til].second = next_y;
                vis[next_x][next_y] = 1;
                t[next_x][next_y] = t[q.first][q.second] + 1;
//                cout << next_x << " " << next_y << " " << t[next_x][next_y] << endl;
                til++;
            }
        }
        frt++;
    }
    return;
}
int bfsj()
{
    memset(step,0,sizeof(step));
    P qu[1010];
    int frt = 0,til = 0;
    qu[til].first = jx;
    qu[til++].second = jy;
    step[jx][jy] = 0;
    while(frt < til)
    {
        P p = qu[frt];
        int next_x,next_y;
        for(int i = 0;i < 4; i++)
        {

            next_x = p.first + mv[i][0];
            next_y = p.second + mv[i][1];
            if(next_x >= 0 && next_x < r && next_y >= 0 && next_y < c && mp[next_x][next_y] != '#' && (step[next_x][next_y] < t[next_x][next_y]))
            {
                qu[til].first = next_x;
                qu[til].second = next_y;
                step[next_x][next_y] = step[p.first][p.second] + 1;
//                cout << next_x << " " << next_y << " " << step[next_x][next_y] << endl;
                til++;
            }
            if((next_x == 0 || next_x == r - 1 || next_y == 0 || next_y == c - 1) && next_x >= 0 && next_x < r && next_y >= 0 && next_y < c && mp[next_x][next_y] != '#' && (step[next_x][next_y] < t[next_x][next_y])){
//                printf("###\n");
                return step[next_x][next_y] + 1;
            }
        }
        frt++;
    }
    return -1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d",&r,&c);
        getchar();
        for(int i = 0;i < r; i++)
        {
            scanf("%s",mp[i]);
            for(int j = 0;j < c; j++)
            {
                if(mp[i][j] == 'J')
                    jx = i,jy = j;
                if(mp[i][j] == 'F')
                    fx = i,fy = j;
            }
        }
        bfsfire();
//        printf("!!!\n");
        int ans = bfsj();
        //cout << step[1][1] << endl;
        ans == -1 ? printf("IMPOSSIBLE\n") : printf("%d\n",ans);
    }
    return 0;
}