【无标题】

一个迷宫可以看作一个 R 行 C 列的方格矩阵。

其中一些方格是空地,用 . 表示,其他方格是障碍,用 # 表示。

开始时,乔位于一块空地之中。

迷宫中一些空地已经起火了,幸运的是火还没有蔓延至乔所在的位置。

为了避免被火烧伤,乔需要尽快逃离迷宫。

已知,乔每单位时间只能沿上下左右四个方向前进一格距离,并且在前进过程中,他不能进入障碍方格。

火每单位时间都会蔓延至其上下左右四个方向的相邻空地,但是火也会被障碍阻挡。

如果一个方格已经起火或者会在乔进入方格的那一时刻恰好起火,则该方格很危险,乔不能进入。

当乔进入到任意一个位于边界的空地方格时,他都可以再花费一单位时间,直接逃离迷宫。

请问,乔想要逃离迷宫,最少需要花费的时间。

输入格式

第一行包含整数 T,表示共有 T 组测试数据。

每组数据第一行包含两个整数 R,C。

接下来 R 行,包含一个 R×C 的字符矩阵。

矩阵中只包含以下四种字符:

  • # 表示障碍方格。
  • . 表示空地方格。
  • J 表示乔所在的空地方格,最多只有一个。
  • F 表示已经起火的空地方格。

输出格式

每组数据输出一行结果,一个整数表示逃离迷宫所需花费的最少时间,如果无法逃离迷宫,则输出 IMPOSSIBLE

数据范围

1≤T≤10
1≤R,C≤1000。

输入样例:

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

输出样例:

3
IMPOSSIBLE

 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define x first
#define y second

using namespace std;

typedef pair PII;

const int N = 1010, INF = 0x3f3f3f3f;

int n, m;
char g[N][N];
int d[N][N], w[N][N];
vector fire;

void bfs()
{
    queue q;
    int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

    for (auto& [x, y] : fire)
        q.push({x, y}), d[x][y] = 0;

    while (q.size())
    {
        PII t = q.front();
        q.pop();

        for (int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if (a < 1 || a > n || b < 1 || b > m) continue;
            if (d[a][b] != INF || g[a][b] != '.') continue;
            d[a][b] = d[t.x][t.y] + 1;
            q.push({a, b});
        }
    }

}

int BFS(int sx, int sy)
{
    if (sx == 1 || sx == n || sy == 1 || sy == m) return 1;
    queue q;
    int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
    q.push({sx, sy});
    w[sx][sy] = 0;

    while (q.size())
    {
        PII t = q.front();
        q.pop();

        for (int i = 0; i < 4; i ++ )
        {
            int a = t.x + dx[i], b = t.y + dy[i];
            if (a < 1 || a > n || b < 1 || b > m) continue;
            if (w[a][b] != INF|| g[a][b] != '.' || w[t.x][t.y] + 1 >= d[a][b]) continue;
            w[a][b] = w[t.x][t.y] + 1;
            if (a == 1 || a == n || b == 1 || b == m) return w[a][b] + 1;
            q.push({a, b});
        }

    }

    return -1;
}

int main()
{

    int T;
    cin >> T;

    while (T -- )
    {
        cin >> n >> m;

        for (int i = 1; i <= n; i ++ ) cin >> g[i] + 1;

        fire.clear();
        memset(d, 0x3f, sizeof d);
        memset(w, 0x3f, sizeof w);

        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= m; j ++ )
                if (g[i][j] == 'F') fire.push_back({i, j});

        bfs();

        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= m; j ++ )
                if (g[i][j] == 'J')
                {
                    int res = BFS(i, j);

                    if (res == -1) puts("IMPOSSIBLE");
                    else cout << res << endl;
                    break;
                }
    }

    return 0;
}

 

你可能感兴趣的:(c++,算法)