• 洛谷 1363 幻想迷宫


    这是一道不是很难的搜索题,我的第一反应是把矩阵扩大九倍,然后从中间子阵的起点做flood_fill即可。

    然后提交,WA,桑心,反思,不解,下样例:终于发现,仅仅扩大九倍是不够的,极端数据可以要求穿过更多的子阵才能到达。

    于是,我加了四行代码:

                if (nx > n + (n << 1)) nx -= n + (n << 1);
                if (ny > m + (m << 1)) ny -= m + (m << 1); 
                if (nx < 1) nx = n + (n << 1);
                if (ny < 1) ny = m + (m << 1); 

    终于AC:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    
    int m, n, sx, sy, nx, ny;
    
    int dx[] = {0, 0, 1, -1};
    int dy[] = {1, -1, 0, 0};
    
    char ch;
    char c[5000][5000];
    
    bool vis[5000][5000];
    bool v[2000][2000];
    bool pt;
    
    struct node 
    {
        int x;
        int y;
    }cur, fir;
    
    void flood_fill(int x, int y)
    {
        fir.x = x;
        fir.y = y;
        queue <node> Q;
        Q.push(fir);
        v[x%n == 0 ? n : x%n][y%m == 0 ? m : y%m] = 1;
        vis[x][y] = 1;
        while (!Q.empty())
        {
            cur = Q.front();
            Q.pop();
            for (int i = 0; i < 4; ++i)
            {
                nx = cur.x + dx[i];
                ny = cur.y + dy[i];
                if (nx > n + (n << 1)) nx -= n + (n << 1);
                if (ny > m + (m << 1)) ny -= m + (m << 1); 
                if (nx < 1) nx = n + (n << 1);
                if (ny < 1) ny = m + (m << 1); 
                if (c[nx][ny] == '#' || nx < 1 || ny < 1 || nx > n + (n << 1) || ny > m + (m << 1) || vis[nx][ny]) continue;
                if (v[nx%n == 0 ? n : nx%n][ny%m == 0 ? m : ny%m] == 1) { pt = true; goto good; }
                v[nx%n == 0 ? n : nx%n][ny%m == 0 ? m : ny%m] = 1;
                vis[nx][ny] = 1;
                fir.x = nx;
                fir.y = ny;
                Q.push(fir);
            }
        } 
        good:;
    }
    
    int main()
    {
        while (cin >> n >> m)
        {
            memset(v, false, sizeof(v));
            memset(vis, false, sizeof(vis));
            for (int i = 1; i <= n; ++i)
                for (int j = 1; j <= m; ++j)
                {
                    cin >> c[i][j];
                    if (c[i][j] == 'S')
                        sx = i, sy = j, c[i][j] = '.';
                    ch = c[i][j];
                    c[i][j + m] = ch;
                    c[i][j + (m << 1)] = ch;
                    c[i + n][j] = ch;
                    c[i + n][j + m] = ch;
                    c[i + n][j + (m << 1)] = ch;
                    c[i + (n << 1)][j] = ch;
                    c[i + (n << 1)][j + m] = ch;
                    c[i + (n << 1)][j + (m << 1)] = ch;
                }
            pt = false;
            flood_fill(sx + n, sy + m);
            if (pt) puts("Yes");
            else puts("No");
        }
    }
  • 相关阅读:
    Codeforces Round #687 A. Prison Break
    最小生成树自用笔记(Kruskal算法+prim算法)
    Codeforces Round #686 (Div. 3)(A->D)(模拟,vector,数学)
    Acwing 852. spfa判断负环
    Linux内核分析_课程学习总结报告
    结合中断上下文切换和进程上下文切换分析Linux内核的一般执行过程
    深入理解系统调用
    基于mykernel 2.0编写一个操作系统内核
    何评测一个软件工程师的计算机网络知识水平与网络编程技能水平?——参考试题
    TCP三次握手Linux源码解析
  • 原文地址:https://www.cnblogs.com/yanyiming10243247/p/9758268.html
Copyright © 2020-2023  润新知