Fire! UVA - 11624
思路:看到题之后有两种思路1、火走一步人走一步,人只要能在火之前走到边界边成功,2、先预处理火到达每个格子的时间,只要人走到这个格子的时间小于火走到的时间就可以走(不过不知道为什么处理了半天还是WA)
注意:火可以不止一个
具体代码如下:
#include<iostream>
#include<queue>
#include<cstring>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 1010;
int n, m;
int d[N][N];
char g[N][N];
queue<PII> Joe, Fire;
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
void init(){
while(Joe.size()) Joe.pop();
while(Fire.size()) Fire.pop();
memset(d, -1, sizeof d);
}
void fire(){
int x = Fire.size();
while(x--){
PII t = Fire.front();
Fire.pop();
for(int i=0; i<4; ++i){
int a = t.x + dx[i], b = t.y + dy[i];
if(a < 0 || a >= n || b < 0 || b >= m) continue;
if(d[a][b] != -1) continue;
if(g[a][b] == '#') continue;
d[a][b] = -2;//火走过的地方值设为-2
Fire.push({a, b});
}
}
}
int bfs(){
while(Joe.size()){
int x = Joe.size();
fire(); //火走一格
while(x--){ //人走一格
PII t = Joe.front();
Joe.pop();
if(t.x == 0 || t.x == n-1 || t.y == 0 || t.y == m-1) return d[t.x][t.y] + 1;
for(int i=0; i<4; ++i){
int a = t.x + dx[i], b = t.y + dy[i];
if(a < 0 || a >= n || b < 0 || b >= m) continue;
if(d[a][b] != -1) continue;
if(g[a][b] == '#') continue;
d[a][b] = d[t.x][t.y] + 1;
Joe.push({a, b});
}
}
}
return 0;
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
init();
for(int i=0; i<n; ++i) scanf("%s", &g[i]);
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
if(g[i][j] == 'J'){
d[i][j] = 0;
Joe.push({i, j});
}else if(g[i][j] == 'F'){
d[i][j] = -2;
Fire.push({i, j});
}
int res = bfs();
if(res) printf("%d\n", res);
else puts("IMPOSSIBLE");
}
return 0;
}