2603 逃出城堡
小Biu被困在一个城堡中,城堡可以看成一个大小为n*n的二维平面上的网格图,
每一个格子要么为平地,要么为墙壁,要么为毒区,而且作为毒区的格子,每
一秒会向他周围的上下左右四个格子扩散毒气(毒气不能穿过墙壁)。现在小Biu
身负重任,最开始小Biu在某一个平地上,他每一秒可以向他上下左右四个格子
中的作为平地的格子移动一步,他想知道如果不能穿越墙壁,也不能接触有毒
气的格子(如果毒气和小Biu同时到达某个平地,也算接触),他最少需要多长时间
才能逃出城堡,只要从任何一个边缘走出城堡都算逃出城堡。
如图所示的数据中,只要小Biu先向右移动两步,再向下移动两步,即可逃出城,所以答案为4。
输入
第1行:一个整数n,表示城堡的大小是一个n*n的网格图。(1<=n<=1000) 第2-n+1行:每一行有n个字符,'.'表示平地,'*'表示有毒气的格子,'#'表示墙壁,'S'表示小Biu最开始的 位置。输出
输出一个整数表示答案,如果小Biu不能逃出城堡则输出"IMPOSSIBLE"(不带引号)。输入样例
5 .*... ....# .*..# #S..# .##.# 6 ###### ##S### ...... ..*... ###### ######输出样例
4 IMPOSSIBLE
思路:
暴力一点可以两次bfs,一次毒气走,一次人走。
技巧一点可以一次bfs,人和毒气同时走,但是同一阶段,毒气先走人再走。
bfs注意一下稍加区分即可。
两次bfs代码实现:
#include
#include
#include
#include
#include
一次多源点bfs题解:
#include
#include
#include
#include
#include
#include
#include
#define itn int
#define reaD read
#define N 1005
using namespace std;
int n, x, y, ans = 0x3f3f3f3f;
int u[4] = { -1, 0, 1, 0 }, v[4] = { 0, 1, 0, -1 };
struct node {
int x, y, t, opt;
};
bool vis[N][N];
char mp[N][N];
queue q;
inline int read() {
int x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') {
if (c == '-') w = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
x = x * 10 + c - '0';
c = getchar();
}
return x * w;
}
void bfs() {
while(!q.empty()) {
node tmp = q.front();
q.pop();
int x = tmp.x, y = tmp.y, t = tmp.t;
for(int i = 0; i < 4; i++) {
int tx = x + u[i], ty = y + v[i];
if(tx < 1 || tx > n || ty < 1 || ty > n) {
if(tmp.opt) {
ans = t + 1;
return;
} else continue;
}
if(vis[tx][ty]) continue;
q.push((node) {
tx, ty, t + 1, tmp.opt
});
vis[tx][ty] = 1;
}
}
}
int main() {
n = reaD();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++) {
mp[i][j] = getchar();
if(mp[i][j] == '\n') mp[i][j] = getchar();
if(mp[i][j] == '*') {
vis[i][j] = 1;
q.push((node) {
i, j, 0, 0
});
}
if(mp[i][j] == '#')
vis[i][j] = 1;
if(mp[i][j] == 'S')
x = i, y = j;
}
vis[x][y] = 1;
q.push((node) {
x, y, 0, 1
});
bfs();
if(ans == 0x3f3f3f3f) puts("IMPOSSIBLE");
else printf("%d\n", ans);
return 0;
}
THE END;