当前位置:首页 > 洛谷 > 洛谷1363题解法:虚拟坐标优化BFS解决循环迷宫问题(附代码详解)

洛谷1363题解法:虚拟坐标优化BFS解决循环迷宫问题(附代码详解)

3天前

洛谷1363题解法:虚拟坐标优化BFS解决循环迷宫问题(附代码详解) 洛谷1363题 BFS算法 算法优化 C++代码 广度优先搜索 迷宫逃脱 竞赛编程 第1张

一、题目解读

洛谷1363题要求判断在给定大小的循环迷宫中,从起点出发是否可以通过移动到达多个不同的路径方向。迷宫由字符矩阵表示,'S'为起点,'#'为障碍物,其余为可通行区域。由于迷宫存在循环(即超出边界后从另一侧重新进入),需判断是否存在多条有效路径,避免陷入无限循环。

二、解题思路

核心思路为广度优先搜索(BFS)结合虚拟坐标。普通BFS无法处理循环迷宫中的路径重复问题,因此引入虚拟坐标(virtX, virtY)记录每个位置的“相对位移”。每当到达新节点时,若其虚拟坐标与已访问节点不同,说明存在多条路径,即可判定可逃脱。

三、解题步骤

1. 初始化:读取迷宫矩阵,定位起点(startX, startY),初始化队列和访问标记。

2. BFS遍历:从起点开始,依次遍历上、下、左、右四个方向。

3. 边界处理:使用取模运算实现循环边界(如nx = (x + dx + n) % n),确保坐标合法。

4. 虚拟坐标更新:每次移动时,虚拟坐标根据相对位移计算(vx = virtX[x][y] + dx)。

5. 关键判断:若新节点未被访问,标记并加入队列;若已被访问且虚拟坐标不同,直接返回True(可逃脱)。

6. 终止条件:队列为空时仍未找到不同路径,则返回False。

四、代码与注释

#include <iostream>
#include <queue>
#include <cstring>
using namespace std;

const int N = 1505;
char grid[N][N];
bool vis[N][N];
int virtX[N][N], virtY[N][N];
int n, m, startX, startY;
int dirs[4][2] = {{0,1},{0,-1},{1,0},{-1,0}};

bool canEscape() {
    queue<pair<int,int>> q;
    q.push({startX, startY});
    vis[startX][startY] = true;
    virtX[startX][startY] = startX; // 初始化虚拟坐标
    virtY[startX][startY] = startY;

    while (!q.empty()) {
        auto [x,y] = q.front(); q.pop();
        
        for (auto [dx,dy] : dirs) {
            int nx = (x + dx + n) % n; // 循环边界处理
            int ny = (y + dy + m) % m;
            int vx = virtX[x][y] + dx; // 更新虚拟坐标
            int vy = virtY[x][y] + dy;

            if (grid[nx][ny] == '#') continue; // 障碍物跳过

            if (!vis[nx][ny]) { // 未访问节点
                vis[nx][ny] = true;
                virtX[nx][ny] = vx;
                virtY[nx][ny] = vy;
                q.push({nx, ny});
            } 
            else if (virtX[nx][ny]!= vx || virtY[nx][ny]!= vy) { // 关键判断:路径方向不同
                return true; // 存在多条路径,可逃脱
            }
        }
    }
    return false; // 未找到不同路径
}

int main() {
    while (cin >> n >> m) {
        memset(vis, 0, sizeof(vis));
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cin >> grid[i][j];
                if (grid[i][j] == 'S') {
                    startX = i; startY = j;
                }
            }
        }
        cout << (canEscape()? "Yes" : "No") << endl;
    }
    return 0;
}

五、总结

本解法通过虚拟坐标巧妙解决循环迷宫的路径多样性问题,避免了传统BFS在循环结构中的冗余判断。核心在于利用相对位移记录路径方向,通过对比虚拟坐标快速确定是否存在多条有效路径,从而优化算法逻辑。该思路对处理类似循环问题具有通用性,是算法设计与优化的典型范例。


原创内容 转载请注明出处

分享给朋友:

相关文章

牛客3750题解题报告:滑动窗口最大值的高效解法(C++代码详解)

牛客3750题解题报告:滑动窗口最大值的高效解法(C++代码详解)

一、题目解读牛客3750题要求在一个给定的整数数组中,计算指定窗口大小下的滑动窗口最大值。例如,输入数组num=[1,3,-1,-3,5,3,6,7],窗口大小为size=3时,需输出每个窗口内的最大...

【力扣3115题解】数组中质数最大差值的求解(C++代码详解)

【力扣3115题解】数组中质数最大差值的求解(C++代码详解)

一、题目解读力扣3115题要求在一个整数数组中,找出两个质数之间的最大差值。若数组不存在质数,则返回0。题目核心在于高效筛选质数,并计算其索引差值的最大值,需兼顾时间与空间复杂度。二、解题思路参考代码...

牛客网288555题解题指南:动态规划求解小红的暑假(附代码解析)

牛客网288555题解题指南:动态规划求解小红的暑假(附代码解析)

一、题目解读牛客网288555题要求解决一个组合数学问题:有三位朋友,每天需邀请其中一位参加聚会,但不能连续两天邀请同一位朋友。给定天数n,求满足条件的不同邀请方案总数。题目考察动态规划、状态转移及组...

洛谷P2346四子连珠游戏最短步数BFS解法详解

洛谷P2346四子连珠游戏最短步数BFS解法详解

一、题目解读洛谷P2346是一道经典的棋盘游戏问题,要求在一4x4黑白棋棋盘上,通过移动棋子使同色棋子形成四子一线(横、竖或对角线),计算达成目标所需的最少步数。题目考察BFS算法应用和状态空间搜索能...

力扣2771题解析:双数组动态规划求解最长非递减子数组问题

力扣2771题解析:双数组动态规划求解最长非递减子数组问题

一、题目解读力扣2771题要求从两个整数数组nums1和nums2中合并元素,寻找最长非递减子数组的长度。非递减子数组指元素单调递增或相等的连续序列。题目难点在于需同时考虑两个数组的交互关系,找到全局...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。