【YbtOJ高效進階 廣搜-6】逃離噩夢
阿新 • • 發佈:2021-01-26
小目錄
連結
題目描述
樣例輸入
1
5 6
XXXXXX
XZZ..X
XXXXXX
M.....
..G...
樣例輸出
1
思路
ababab
兩個BFS,一個走男生,一個走女生,然後每次都判斷是否再鬼的範圍內
然後男生的三步可以拆成三步,全部走完之後再弄成走多一步的時間
最後會合之後再判斷鬼會不會擴到(那如果不能會合那不就肯定被鬼啃掉
那為啥我會MLE一個早上呢?玄學
然後瞎改一通稀裡糊塗地就A了(感謝TJH神仙
程式碼
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct tQ {
int x, y, val;
} now;
bool a[1001][1001], in_b[1001][1001], in_g[1001][1001];
int T, re, f, n, m, mx, my, gx, gy, zx[3], zy[3], tmp;
int dx[4] = { 1, -1, 0, 0 }, dy[4] = { 0, 0, 1, -1 };
queue<tQ> Q_b, Q_g;
char c;
int read() {
re = 0;
f = 1;
c = getchar();
while (c < '0' || c > '9') {
if (c == '-')
f = -f;
c = getchar();
}
while (c >= '0' && c <= '9') {
re = re * 10 + c - '0';
c = getchar();
}
return re * f;
}
bool ingoest(int x, int y, int val) {
for (int i = 1; i <= 2; i++) {
if (abs(x - zx[i]) + abs(y - zy[i]) <= 2 * val + 2)//+2是因為鬼先動,人再走
return 1;
}
return 0;
}
bool ch(int x, int y) {
if (x < 1 || x > n)
return 0;
if (y < 1 || y > m)
return 0;
return 1;
}
bool bfs() {
while (!Q_g.empty()) Q_g.pop();
while (!Q_b.empty()) Q_b.pop();
memset(in_g, 0, sizeof(in_g));
memset(in_b, 0, sizeof(in_b));
Q_b.push((tQ){ mx, my, 0 });
in_b[mx][my] = 1;
Q_g.push((tQ){ gx, gy, 0 });
in_g[gx][gy] = 1;
while (!Q_b.empty() || !Q_g.empty()) {
if (!Q_b.empty()) {
for (int step = 1; step <= 3; step++) {
tmp = Q_b.size();
for (int num = 1; num <= tmp; num++) {
now = Q_b.front();
Q_b.pop();
if (ingoest(now.x, now.y, now.val))
continue;
for (int i = 0; i < 4; i++)
if (ch(now.x + dx[i], now.y + dy[i]))
if (!in_b[now.x + dx[i]][now.y + dy[i]] && a[now.x + dx[i]][now.y + dy[i]]) {
if (!ingoest(now.x + dx[i], now.y + dy[i], now.val) &&
in_g[now.x + dx[i]][now.y + dy[i]]) {
printf("%d\n", now.val + 1);
return 1;
}
in_b[now.x + dx[i]][now.y + dy[i]] = 1;
Q_b.push((tQ){ now.x + dx[i], now.y + dy[i], now.val });
}
}
}
tmp = Q_b.size();
for (int num = 1; num <= tmp; num++) {
now = Q_b.front();
Q_b.pop();
Q_b.push((tQ){ now.x, now.y, now.val + 1 });
}
}//賦給新的時間
if (!Q_g.empty()) {
tmp = Q_g.size();
for (int num = 1; num <= tmp; num++) {
now = Q_g.front();
Q_g.pop();
if (!ingoest(now.x, now.y, now.val)) {
for (int i = 0; i < 4; i++)
if (ch(now.x + dx[i], now.y + dy[i]))
if (!in_g[now.x + dx[i]][now.y + dy[i]] && a[now.x + dx[i]][now.y + dy[i]]) {
if (!ingoest(now.x + dx[i], now.y + dy[i], now.val) &&
in_b[now.x + dx[i]][now.y + dy[i]]) {
printf("%d\n", now.val + 1);
return 1;
}
in_g[now.x + dx[i]][now.y + dy[i]] = 1;
Q_g.push((tQ){ now.x + dx[i], now.y + dy[i], now.val + 1 });
}
}
}
}
}
return 0;
}
char readc() {
char c = getchar();
while (c != 'X' && c != 'Z' && c != '.' && c != 'M' && c != 'G') c = getchar();
return c;
}
int main() {
T = read();
for (int times = 1; times <= T; times++) {
n = read();
m = read();
zx[0] = 0;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
c = readc();
if (c == '.' || c == 'M' || c == 'G') {
a[i][j] = 1;
if (c == 'M') {
mx = i;
my = j;
}
if (c == 'G') {
gx = i;
gy = j;
}
}
if (c == 'Z') {
zx[++zx[0]] = i;
zy[zx[0]] = j;
a[i][j] = 0;
}
if (c == 'X')
a[i][j] = 0;
}//讀入處理
if (!bfs())
printf("-1\n");
}
return 0;
}