P1363 幻象迷宫

1|0P1363 幻象迷宫

1|1判断无限路径(判环)

难点就在判断该点是否会无限走过。

思路是维护目前 (x,y) 下的传送次数,和历史上 (x,y) 的传送次数。

如果 (x,y) 已经被走过,且传送次数又和历史上不同,说明已经开始无限循环了。

#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAXN = 1500 + 1; const int dx[4] = {1, -1, 0, 0}; const int dy[4] = {0, 0, 1, -1}; int n, m; int st_x, st_y; int vis[MAXN][MAXN][3]; bool fl, a[MAXN][MAXN]; char ch; void dfs(int x, int y, int lx, int ly) { if(fl) return; if(vis[x][y][0] && (vis[x][y][1]!=lx || vis[x][y][2]!=ly)) { fl = 1; return; } vis[x][y][1] = lx, vis[x][y][2] = ly, vis[x][y][0] = 1; for(int i=0; i<4; ++i) { int xx = (x + dx[i] + n) % n, yy = (y + dy[i] + m) % m; int lxx = lx + dx[i], lyy = ly + dy[i]; if(!a[xx][yy]) { if(vis[xx][yy][1]!=lxx || vis[xx][yy][2]!=lyy || !vis[xx][yy][0]) dfs(xx, yy, lxx, lyy); } } } int main() { ios::sync_with_stdio(false); while(cin >> n >> m) { fl = 0; memset(a, 0, sizeof(a)); memset(vis, 0, sizeof(vis)); for(int i=0; i<n; ++i) for(int j=0; j<m; ++j) { cin >> ch; if(ch == '#') a[i][j] = 1; if(ch == 'S') st_x = i, st_y = j; } dfs(st_x, st_y, st_x, st_y); if(fl) puts("Yes"); else puts("No"); } }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17865485.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(4)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示