传送门.
思路:
两个bfs,一个bfs搜火的路径,一个搜人的路径,最后在图的四条边界判断人是否比火先到即可;
注意有一个坑点,就是火不止有一处,所以在火的bfs中我开了全局的队列,在main里push进去火的位置
这个题刚开始用d数组一边记录走的时间,一边记录是否被搜过,然后wa了好多次,最后多开了一个数组来记录是否被搜过才ac QAQ~
相似题目:
QWQ
代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#include <queue>
#include <utility>
#include <stack>
#define me memset
using namespace std;
typedef long long ll;
typedef pair<int,int>PII;
const int N = 1010;
const int null = 0x3f3f3f3f;
int T;
int r,c;
int jx,jy;
bool st[N][N];
int dj[N][N],df[N][N];
int dx[4] = {0,1,0,-1},dy[4] = {1,0,-1,0};
string s[N];
void bfsj()
{
me(dj,0x3f,sizeof dj);
dj[jx][jy] = 0;
queue<PII> q;
q.push({jx,jy});
st[jx][jy] = true;
while(q.size())
{
auto t = q.front();
q.pop();
for(int i = 0;i < 4;i ++)
{
int x = t.first + dx[i];
int y = t.second + dy[i];
if(x >= 0 && x < r && y >= 0 && y < c && !st[x][y] && s[x][y] != '#')
{
q.push({x,y});
dj[x][y] = dj[t.first][t.second] + 1;
st[x][y] = true;
}
}
}
}
queue<PII> qe;
void bfsf()
{
while(qe.size())
{
auto t = qe.front();
qe.pop();
for(int i = 0;i < 4;i ++)
{
int x = t.first + dx[i];
int y = t.second + dy[i];
if(x >= 0 && x < r && y >= 0 && y < c && !st[x][y] && s[x][y] != '#')
{
qe.push({x,y});
df[x][y] = df[t.first][t.second] + 1;
st[x][y] = true;
}
}
}
}
int main()
{
cin >> T;
while(T --)
{
cin >> r >> c;
me(df,0x3f,sizeof df);
for(int i = 0;i < r;i ++)
{
cin >> s[i];
// cout << s[i] << endl;
for(int j = 0;j < c;j ++)
{
if(s[i][j] == 'J') jx = i,jy = j;
if(s[i][j] == 'F')
{
df[i][j] = 0;
st[i][j] = true;
qe.push({i,j});
}
}
}
// cout << jx << " " << jy << " " << fx << " " << fy << endl;
bfsf();
me(st,0,sizeof st);
bfsj();
int ans = null;
int k = 0;
for(int i = 0;i < c;i ++)
{
// cout << i << " " << ans << endl;
if(dj[k][i] < df[k][i]) ans = min(ans,dj[k][i]);
}
for(int i = 0;i < r;i ++)
{
// cout << i << " " << ans << endl;
if(dj[i][k] < df[i][k]) ans = min(ans,dj[i][k]);
}
k = r - 1;
for(int i = 0;i < c;i ++)
{
// cout << i << " " << ans << endl;
if(dj[k][i] < df[k][i]) ans = min(ans,dj[k][i]);
}
k = c - 1;
for(int i = 0;i < r;i ++)
{
// cout << i << " " << ans << endl;
if(dj[i][k] < df[i][k]) ans = min(ans,dj[i][k]);
}
if(ans == null) printf("IMPOSSIBLE\n");
else printf("%d\n",ans + 1);
me(st,0,sizeof st);
}
}