1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
| #include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std;
const int N = 810;
int T, n, m; char a[N][N]; int dx[] = {1, -1, 0, 0}; int dy[] = {0, 0, -1, 1};
struct node { int x, y; }; node ghost[2]; int vis[2][N][N]; queue<node> Q[2]; int step;
bool check(int x, int y) { if(x<1 || x>n || y<1 || y>m || a[x][y] == 'X') { return 0; } else if(abs(x-ghost[0].x) + abs(y-ghost[0].y) <= step*2) { return 0; } else if(abs(x-ghost[1].x) + abs(y-ghost[1].y) <= step*2) { return 0; } return 1; }
bool bfs(int idx) { int size = Q[idx].size(); while(size--) { node now = Q[idx].front(); Q[idx].pop(); if(!check(now.x, now.y)) continue; for(int i = 0; i < 4; i++) { int x = now.x + dx[i]; int y = now.y + dy[i]; if(!check(x, y) || vis[idx][x][y]) continue; if(vis[1-idx][x][y]) return 1; vis[idx][x][y] = 1; Q[idx].push((node){x, y}); } } return 0; }
int main() { cin >> T; while(T--) { step = 0; memset(vis, 0, sizeof(vis)); while(Q[0].size()) Q[0].pop(); while(Q[1].size()) Q[1].pop(); scanf("%d%d", &n, &m); int sx = 0, sy = 0, ex = 0, ey = 0; int tot = 0; for(int i = 1; i <= n; i++) { scanf("%s", a[i]+1); for(int j = 1; j <= m; j++) { if(a[i][j] == 'M') { sx = i; sy = j; } else if(a[i][j] == 'G') { ex = i; ey = j; } else if(a[i][j] == 'Z') { ghost[tot].x = i; ghost[tot].y = j; tot++; } } } Q[0].push((node){sx, sy}); Q[1].push((node){ex, ey}); int f = 0; while(Q[0].size() || Q[1].size()) { ++step; for(int i = 1; i <= 3; i++) { if(bfs(0)) { f = 1; break; } } if(bfs(1)) { f = 1; break; } } if(f) printf("%d\n", step); else printf("-1\n"); }
return 0; }
|