#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e3 + 10;
#define Dis(a,b) abs((a).x-(b).x)+abs((a).y-(b).y)
int dir[4][2] = {{ -1, 0}, {1, 0}, {0, -1}, {0, 1}};
bool vis[maxn][maxn][2];
char inp[maxn][maxn];
int n, m, T, cnt;
struct Node
{
int x, y;
Node(int x = 0, int y = 0): x(x), y(y) {}
Node move(int i)
{
return Node(x + dir[i][0], y + dir[i][1]);
}
bool Judge();
};
queue<Node>Q[2];
Node M, G, Z[2];
bool Node::Judge()
{
if (x >= 0 && x < n && y >= 0 && y < m && inp[x][y] != 'X')
{
if (Dis(*this, Z[0]) <= 2 * cnt || Dis(*this, Z[1]) <= 2 * cnt)
return false;
else return true;
}
else return false;
}
int BFS(int num)
{
int k = Q[num].size();
while (k--)
{
Node pos = Q[num].front(); Q[num].pop();
if (pos.Judge())
for (int i = 0; i < 4; i++)
{
Node tmp = pos.move(i);
if (tmp.Judge() && !vis[tmp.x][tmp.y][num])
{
if (vis[tmp.x][tmp.y][!num]) return true;
else vis[tmp.x][tmp.y][num] = true, Q[num].push(tmp);
}
}
}
return false;
}
int Dual_BFS()
{
memset(vis, 0, sizeof(vis));
while (!Q[0].empty()) Q[0].pop();
while (!Q[1].empty()) Q[1].pop();
Q[0].push(M); Q[1].push(G);
vis[M.x][M.y][0] = vis[G.x][G.y][1] = true;
cnt = 0;
while (!Q[0].empty() || !Q[1].empty())
{
cnt++;
if (BFS(0) || BFS(0) || BFS(0) || BFS(1))
return cnt;
}
return -1;
}
int main(int argc, char const *argv[])
{
scanf("%d", &T);
while (T--)
{
cnt = 0;
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
{
scanf("%s", inp[i]);
for (int j = 0; j < m; j++)
{
if (inp[i][j] == 'M') M = Node(i, j);
else if (inp[i][j] == 'G') G = Node(i, j);
else if (inp[i][j] == 'Z') Z[cnt++] = Node(i, j);
}
}
printf("%d\n", Dual_BFS());
}
return 0;
}
男人一次走三格,女人一下走一格,不能翻墙,鬼一下走两格,可以翻墙。问男女能否相遇。
是否会被鬼抓住,直接用两点之间的曼哈顿距离判定就可以了。双向广搜避免超时。
男人一次走三格,女人一下走一格,不能翻墙,鬼一下走两格,可以翻墙。问男女能否相遇。