HDU 3085 (双向BFS + 曼哈顿距离)

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;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/81635786