[LuoguP1363]幻想迷宫(Link

现在有一个迷宫,从迷宫边界的任意一点可以走到对面,即:若都是路面,则可以从\((1, i)\)走到\((N, i)\)。其余情况依旧。问是否可以从指定的起点\((Sx, Sy)\)走到无限远的距离。

简化题目中说了什么叫做走到无限远的距离。那么第一种思路就是计算如果某一个边界点可以到达与之相对应的边界点,那么我们就说可以走到无限远的距离。但是仔细思考之后我们发现这个显然不行,因为它没有考虑在路途中可以进行边界传送。列如下面的样例:

我们从起点开始向右走一个距离,然后接着往上也是可以走的,但是上述的方法就不会考虑。因此这么搜显然是不对的。那么我们考虑建立一个新的图:将原图扩大\(8\)块。也就是变成了:

那么我们就知道怎么搞了。按照原来的思路我们从起点开始深搜,然后碰到一个点,他不是原图中的点,但是还原到原图的位置时,我们发现它已经走过了,那么就说明可以走到无限远。但是如果我们是要一直往上走3次,4次呢?那么直接存图显然就是不可取的,既然是有可能无限,那么想到唯一不会爆内存并且可行的方法就是取模。

我们在搜索的时候记录\(4\)个变量分别为\(X, Y, TrueX, TrueY\)。后两个表示真实坐标,前两个表示还原到原图中的坐标位置,也就是取模后的。

当我们走到一个点的时候如果我们发现\(Visit[X][Y] == 1\)并且\(X != TrueX|| Y != TrueY\),那么说明这个点被走了第二遍。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;
typedef long long LL ;
const int MAXN = 1510 ;
const int MAXM = 1510 ;
const int Inf = 0x7fffffff ;
int N, M, Map[MAXN][MAXM], Sx, Sy ;
struct VISIT{
    int V, X, Y ;
}F[MAXN][MAXM] ;
bool Gone ;
int Dx[5] = {0, 1, -1, 0, 0} ;
int Dy[5] = {0, 0, 0, 1, -1} ;

inline int Read() {
    int X = 0, F = 1 ; char ch = getchar() ;
    while (ch > '9' || ch < '0') F = (ch == '-' ? - 1 : 1), ch = getchar() ;
    while (ch >= '0' && ch <= '9') X=(X<<1)+(X<<3)+(ch^48), ch = getchar() ;
    return X * F ;
}

inline void Dfs(int X, int Y, int TrueX, int TrueY) {
    if (Gone) return ;
    if (F[X][Y].V && ((F[X][Y].X != TrueX) || (F[X][Y].Y != TrueY))) {
        Gone = 1 ; return ;
    }
    F[X][Y].V = 1 ; F[X][Y].X = TrueX ; F[X][Y].Y = TrueY ;
    for (int i = 1 ;  i <= 4 ; i ++) {
        int NextX = (X + Dx[i] + N - 1) % N + 1;
        int NextY = (Y + Dy[i] + M - 1) % M + 1;
        int NextXX = TrueX + Dx[i] ;
        int NextYY = TrueY + Dy[i] ;
        if (Map[NextX][NextY]) {
            if (! F[NextX][NextY].V || F[NextX][NextY].X != NextXX || F[NextX][NextY].Y != NextYY)
                Dfs(NextX, NextY, NextXX, NextYY) ;
        }
    }
}

int main() {
    while (cin >> N >> M) {
        memset(Map, 0, sizeof(Map)) ;
        memset(F, 0, sizeof(F)) ;
        Gone = 0 ;
        for (int i = 1 ; i <= N ; i ++)
        for (int j = 1 ; j <= M ; j ++) {
            char ch ; cin >> ch ;
            if (ch == '#') continue ;
            else Map[i][j] =  1 ;
            if (ch == 'S') Sx = i, Sy = j ;
        }
        Dfs(Sx, Sy, Sx, Sy) ;
        puts(Gone ? "Yes" : "No") ;
    }
}

最新文章

  1. D5转Xe点滴
  2. TopFreeTheme精选免费模板【20130703】
  3. 【思路,dp,BigInteger】ZOJ - 2598 Yet Another Digit
  4. noj [1479] How many (01背包||DP||DFS)
  5. jQuery中$.proxy()的原理和使用
  6. 【JSONKit】序列化Dictionary崩溃
  7. Spring事务的传播行为 @Transactional(转)
  8. js 实现倒计时效果
  9. 016_python程序变量抽取配置的几种方式
  10. Numpy 基础学习
  11. AS安装过程中出现的错误
  12. PHP中empty、isset和is_null的具体区别?
  13. 【BZOJ1925】[SDOI2010]地精部落(动态规划)
  14. ASP 运行结果显示空白 --- 是编码的原因。
  15. 判断ArryaList有没有重复对象的方法
  16. SPARQL 入门教程
  17. Bootstrap 3之美01-下载并引入页面
  18. PSI分析
  19. 容器网络之 veth设备
  20. RequestMapping 支持的方法

热门文章

  1. Sprng IOC&amp;AOP&amp;事务梳理 (文章整理new)
  2. Django实现数据库中表格的增删查改
  3. 关于echarts绘制树图形的注意事项(文字倾斜、数据更新、缓存重绘问题等)
  4. C# Task.FromResult的用法
  5. git 远程代码回退
  6. WinForm实现Rabbitmq官网6个案例-Hello World
  7. WebService发布与调用问题:expected: {http://schemas.xmlsoap.org/soap/envelope/}Envelope but found: {http://schemas.xmlsoap.org/wsdl/}definitions
  8. OkHttp3源码详解(三) 拦截器-RetryAndFollowUpInterceptor
  9. 对WebSocket技术的学习与探索(一)
  10. Java和C# RSA加解密相互通信和使用公钥加密传输