【YbtOJ高效进阶 广搜-6】逃离噩梦

链接

YbtOJ高效进阶 广搜-6

题目描述

在这里插入图片描述
(约定的梦幻岛?)( 雾)

样例输入

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

猜你喜欢

转载自blog.csdn.net/LTH060226/article/details/113137455