UVA - 11624 链接
又是一道放火的题
大致思路,火和人同时走,如果火和人同时到达某个点,则人就不能到达,所以人所到达的点应该根据这一步中火到达的点来判断。
因此我们让火先烧,火烧过的地方变成墙,同时这个点进入火的队列,在下一秒它还会继续延申。
这道题有一个坑点就是有多个火源,因为这个我wa了好几次
//Powered by CK
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const int ax[4] = {1, -1, 0, 0};
const int ay[4] = {0, 0, 1, -1};
const int N = 1e3 + 10;
int maze[N][N], n, m;
struct point {
int x, y, step;
point(int a, int b, int c) : x(a), y(b), step(c) {}
};
void solve() {
char c;
queue<point> fq;//火的队列
queue<point> jq;//人的队列
for(int i = 1; i <= n; i++)//初始化两队列
for(int j = 1; j<= m; j++) {
cin >> c;
if(c == '.') maze[i][j] = 0;
else if(c == '#') maze[i][j] = 1;
else if(c == 'F') {
maze[i][j] = 1;
fq.push(point(i, j, 0));
}
else {
maze[i][j] = 0;
jq.push(point(i, j, 0));
}
}
int l;
while(!jq.empty()) {
l = fq.size();
for(int i = 0; i < l; i ++) {//火先走
point temp = fq.front();
fq.pop();
for(int i = 0; i < 4; i++) {
int tempx = temp.x + ax[i];
int tempy = temp.y + ay[i];
if(!maze[tempx][tempy] && tempx > 0 && tempx <= n && tempy > 0 && tempy <= m) {
maze[tempx][tempy] = 1;//变成墙
fq.push(point(tempx, tempy, temp.step + 1));
}
}
}
l = jq.size();
for(int i = 0; i < l; i++) {//人走
point temp = jq.front();
jq.pop();
for(int i = 0; i < 4; i++) {
int tempx = temp.x + ax[i];
int tempy = temp.y + ay[i];
if(tempx > 0 && tempx <= n && tempy > 0 && tempy <= m) {
if(!maze[tempx][tempy]) {
maze[tempx][tempy] = 1;//最短路嘛,走过的路不回头,同时也标记为墙
jq.push(point(tempx, tempy, temp.step + 1));
}
}
else {//出界了代表走出了地图,直接返回
cout << temp.step + 1 << endl;
return ;
}
}
}
}
cout << "IMPOSSIBLE" << endl;
}
int main() {
// freopen("in.txt", "r", stdin);
int t;
cin >> t;
while(t--) {
cin >> n >> m;
memset(maze, 0, sizeof maze);
solve();
}
return 0;
}