题目:J - Fire!
思路:
先将所有Fire
走到每个格子的最短时间BFS
求出来,再将人走到每个格子的最短时间求出来,比较两个时间
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define fi first
#define se second
using namespace std;
const int N = 1010;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> PII;
int r, c;
int dir[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int d[N][N], dd[N][N];
char mp[N][N];
vector<PII> fire;
void bfs()
{
queue <PII> qu;
for(auto &[x, y] : fire)
{
qu.push({x, y});
d[x][y] = 0;
}
while(!qu.empty())
{
PII t = qu.front();
qu.pop();
for(int i = 0; i < 4; i ++)
{
int tx = t.fi + dir[i][0];
int ty = t.se + dir[i][1];
if(tx < 1 || ty < 1 || tx > r || ty > c) continue;
if(d[tx][ty] != INF || mp[tx][ty] != '.') continue;
qu.push({tx, ty});
d[tx][ty] = d[t.fi][t.se] + 1;
}
}
}
int BFS(int sx, int sy)
{
queue <PII> qu;
qu.push({sx,sy});
dd[sx][sy] = 0;
while(!qu.empty())
{
PII t = qu.front();
qu.pop();
for(int i = 0; i < 4; i ++)
{
int tx = t.fi + dir[i][0];
int ty = t.se + dir[i][1];
if(tx < 1 || ty < 1 || tx > r || ty > c) continue;
if(dd[tx][ty] != INF || mp[tx][ty] != '.' || dd[t.fi][t.se] + 1 >= d[tx][ty]) continue;
qu.push({tx, ty});
dd[tx][ty] = dd[t.fi][t.se] + 1;
if(tx == 1 || ty == 1 || tx == r || ty == c) return dd[tx][ty] + 1;
}
}
return -1;
}
int main()
{
int t;
cin >> t;
while(t --)
{
while(!fire.empty()) fire.pop_back();
memset(d, INF, sizeof d);
memset(dd, INF, sizeof dd);
cin >> r >> c;
for(int i = 1; i <= r; i ++)
{
cin >> mp[i] + 1;
for(int j = 1; j <= c; j ++)
{
if(mp[i][j] == 'F') fire.push_back({i, j});
}
}
bfs();
for(int i = 1; i <= r; i ++)
{
for(int j = 1; j <= c; j ++)
{
if(mp[i][j] == 'J')
{
int res = BFS(i, j);
if(res == -1) cout << "IMPOSSIBLE" << endl;
else cout << res << endl;
break;
}
}
}
}
}