http://acm.hdu.edu.cn/showproblem.php?pid=3085
题意:
MM,GG在两处,还有两只幽灵,一张地图, MM可以一次跑3格,GG一次只能跑一格,幽灵一次能感染身边的格子,而感染后的格子能感染其他格子,问:MM能不能在碰到幽灵前相遇,能相遇使出步数,不能输出-1
思路:
MM与GG同时做BFS,找到相遇的最小步数,而与幽灵的距离用曼哈顿距离(两点的距离== abs(a.x - b.x)+abs(a.y - b.y)),可解
曼哈顿距离
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <math.h>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <string.h>
#include <queue>
#include <stack>
#include <deque>
#include <stdlib.h>
#include <bitset>
using namespace std;
#define ll long long
#define ull unsigned long long
const int inf = 0x3f3f3f3f;
const int INF = 0x3f3f3f3f;
const int maxn = 800 + 5;
const int M = 1e9 + 7;
int n, m;
char mp[maxn][maxn];
struct Point{
int x, y;
Point () {}
Point(int _x, int _y) {
x = _x;
y = _y;
}
};
queue<Point> que[2];
Point Z[2];
int vis[2][maxn][maxn];
int step;
int nx[4] = {0, 0, 1, -1};
int ny[4] = {1, -1, 0, 0};
bool judge(Point x) {
if(x.x < 1 || x.x > n || x.y < 0 || x.y >= m) return 0;
if(mp[x.x][x.y] == 'X') return 0;
if(abs(x.x - Z[0].x) + abs(x.y - Z[0].y) <= 2 * step) return 0;
if(abs(x.x - Z[1].x) + abs(x.y - Z[1].y) <= 2 * step) return 0;
return 1;
}
bool bfs(int w) {
int sum = (int)que[w].size();
Point t;
while(sum --) {
t = que[w].front();que[w].pop();
if(!judge(t)) continue;//因为幽灵先行动,所以要判断现在这个点还能不能走
for (int i = 0; i < 4; i ++) {
int tx = t.x + nx[i], ty = t.y + ny[i];
if(!judge(Point(tx, ty))) continue;
if(!vis[w][tx][ty]) {
if(vis[w ^ 1][tx][ty]) return 1;
vis[w][tx][ty] = 1;
que[w].push(Point(tx, ty));
}
}
}
return 0;
}
int doubleBfs() {
while(!que[0].empty() && !que[1].empty()) {
step ++;
if(bfs(0)) return step;
if(bfs(0)) return step;
if(bfs(0)) return step;
if(bfs(1)) return step;
}
return -1;
}
int main(int argc, const char * argv[]) {
int T;
scanf("%d", &T);
while(T --) {
while(!que[0].empty()) que[0].pop();
while(!que[1].empty()) que[1].pop();
memset(vis, 0, sizeof(vis));
int cnt = 0;
scanf("%d %d",&n, &m);
for (int i = 1; i <= n; i ++) {
scanf("%s", mp[i]);
for (int j = 0; j < m; j ++) {
if(mp[i][j] == 'M') {
que[0].push(Point(i, j));
}
if(mp[i][j] == 'G') {
que[1].push(Point(i, j));
}
if(mp[i][j] == 'Z') {
Z[cnt].x = i; Z[cnt ++].y = j;
}
}
}
step = 0;
printf("%d\n", doubleBfs());
}
return 0;
}