• 搜索-幻象迷宫(洛谷P1363)


    考试的时候想了 Tarjan 和 Topsort ,发觉不对,改写玄学贪心:算 S 出发可以穿梭到达的点,以及原图上可以互相到达的点。枚举两个边界上相邻位置的点(比如 (x, 1) 和 (x, m) ),如果能被 S 穿梭到达,且两者可以直接到达(用并查集维护 Orz ),就是可行方案。不过显然有反例,因为两者之间也可以穿梭到达,不过不能与 S 到他们的路线重合……

    这样想就非常恶心。

    直接搜索四周,记录下到达相对位置 (x, y) 的实际坐标(可以是一个负数或者巨大的数)。如果能到达某个相同的相对做标的,是两个不同的实际坐标,那么是有可行方案的。

    题不难,写一发题解是因为这题算上考试时做的时间,我总共做了三个小时 OrzOrz 。

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <ctype.h>
    
    using namespace std;
    
    const int INF = 1e9;
    
    struct node {
        int x, y;
        
        node(int x = 0, int y = 0)
            : x(x), y(y) { }
    };
    
    queue<node> Q;
    int N, M;
    char G[1550][1550];
    int nxt[4][2] = {0,1,0,-1,1,0,-1,0};
    int mk_x[1550][1550], mk_y[1550][1550];
    
    int mm(int v, int m)
    {
        int t = (v % m + m) % m;
        return t ? t : m;
    }
    
    bool bfs(node bg)
    {
        for (int i = 1; i <= N; ++i)
            for (int j = 1; j <= M; ++j)
                mk_x[i][j] = mk_y[i][j] = INF;
        mk_x[bg.x][bg.y] = bg.x, mk_y[bg.x][bg.y] = bg.y;
        while (!Q.empty()) Q.pop();
        Q.push(bg);
        while (!Q.empty()) {
            node p = Q.front();
            Q.pop();
            for (int i = 0; i < 4; ++i) {
                int tx = p.x + nxt[i][0], ty = p.y + nxt[i][1];
                int gx = mm(tx, N), gy = mm(ty, M);
                if (G[gx][gy] == '#' || mk_x[gx][gy] == tx && mk_y[gx][gy] == ty) continue;
                if (mk_x[gx][gy] == INF && mk_x[gx][gy] == INF) {
                    Q.push(node(tx, ty));
                    mk_x[gx][gy] = tx, mk_y[gx][gy] = ty;
                } else {
                    return true;
                }
            }
        }
        return false;
    }
    
    int main()
    {
        
        while (scanf("%d%d", &N, &M) == 2) {
            node bg;
            for (int i = 1; i <= N; ++i) {
                char tt;
                while ((tt = getchar()) != '#' && tt != '.' && tt != 'S');
                G[i][1] = tt;
                if (G[i][1] == 'S') bg = node(i, 1);
                for (int j = 2; j <= M; ++j) {
                    G[i][j] = getchar();
                    if (G[i][j] == 'S') bg = node(i, j);
                }
            }
            if (bfs(bg))
                printf("Yes
    ");
            else
                printf("No
    ");
            
        }
        return 0;
    } 
    
  • 相关阅读:
    Joshua Bloch错了? ——适当改变你的Builder模式实现
    集成基于OAuth协议的单点登陆
    集成基于CAS协议的单点登陆
    数据库设计中的Soft Delete模式
    完成C++不能做到的事
    ExtJS in Review
    DTO – 服务实现中的核心数据
    保存好你的密码 —— 从芝麻金融被攻破说起
    WPF
    C# 反编译防范
  • 原文地址:https://www.cnblogs.com/ghcred/p/9750274.html
Copyright © 2020-2023  润新知