当前位置:首页 > 洛谷 > 洛谷P1126机器人移动问题:基于BFS算法的解题方案与代码

洛谷P1126机器人移动问题:基于BFS算法的解题方案与代码

5个月前 (07-22)

洛谷P1126机器人移动问题:基于BFS算法的解题方案与代码 洛谷题解 BFS算法 三维数组 广度优先搜索 广搜 C++ 第1张

一、题目解读

洛谷P1126题要求解决一个机器人移动问题:在一个n×m的网格中,机器人占用相邻的4个格子,初始位置和方向已知,需通过左转、右转、前进1-3步的指令到达终点。题目需判断是否存在路径,并输出最短时间。关键点在于机器人移动时的位置合法性判断及指令组合。

二、解题思路

采用广度优先搜索BFS算法。核心思想:从起点开始,遍历所有可能的指令组合(左转、右转、前进),记录每个状态(坐标+方向+时间),利用三维标记数组避免重复搜索。方向数组简化移动计算,check函数验证机器人占用格子是否合法,确保每一步的有效性。

三、解题步骤

1. 输入处理:读取网格尺寸n×m及起点、终点坐标和方向。

2. BFS初始化:将起点状态(坐标、方向、时间0)入队,标记已访问。

3. 指令处理循环:

○ 左转/右转:更新方向,标记新状态并入队。

○ 前进1-3步:逐步扩展,若遇到障碍或超出边界停止;合法则标记并更新时间。

4. 终止条件:到达终点时返回时间,否则无法到达返回-1。

四、代码与注释

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

const int N = 55;
struct Node {
    int x, y, dir, time; // 坐标、方向、耗时
};

int n, m;
int grid[N][N];      // 原始网格
bool vis[N][N][4];   // 三维标记数组(坐标+方向)
// 方向数组:东南西北(对应题目给出的1-4)
int dx[4] = {0, 1, 0, -1};
int dy[4] = {1, 0, -1, 0};

bool check(int x, int y) {
    // 检查机器人占用的4个格子是否合法
    if (x < 1 || x >= n || y < 1 || y >= m) return false;
    return!(grid[x][y] || grid[x+1][y] || grid[x][y+1] || grid[x+1][y+1]);
}

int bfs(int sx, int sy, int sdir, int ex, int ey) {
    queue<Node> q;
    q.push({sx, sy, sdir, 0});
    vis[sx][sy][sdir] = true;

    while (!q.empty()) {
        Node cur = q.front(); q.pop();
        // 到达终点
        if (cur.x == ex && cur.y == ey) return cur.time;

        // 处理三种指令:左转、右转、前进
        for (int cmd = 0; cmd < 3; cmd++) {
            Node next = cur;
            if (cmd == 0) { // 左转
                next.dir = (cur.dir + 3) % 4;
            } else if (cmd == 1) { // 右转
                next.dir = (cur.dir + 1) % 4;
            } else { // 前进1-3步
                for (int step = 1; step <= 3; step++) {
                    next.x = cur.x + dx[cur.dir] * step;
                    next.y = cur.y + dy[cur.dir] * step;
                    if (!check(next.x, next.y)) break; // 遇到障碍停止
                    if (vis[next.x][next.y][next.dir]) continue;
                    vis[next.x][next.y][next.dir] = true;
                    next.time = cur.time + 1;
                    q.push(next);
                }
                continue;
            }
            if (!vis[next.x][next.y][next.dir]) {
                vis[next.x][next.y][next.dir] = true;
                next.time = cur.time + 1;
                q.push(next);
            }
        }
    }
    return -1; // 无法到达
}

int main() {
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> grid[i][j];

    int sx, sy, ex, ey;
    char dir;
    cin >> sx >> sy >> ex >> ey >> dir;

    // 转换方向为数字标识
    int sdir;
    if (dir == 'E') sdir = 0;
    else if (dir == 'S') sdir = 1;
    else if (dir == 'W') sdir = 2;
    else sdir = 3;

    cout << bfs(sx, sy, sdir, ex, ey);
    return 0;
}

五、总结

本解法通过BFS结合三维状态标记,高效解决机器人路径规划问题。关键在于对机器人占用格子合法性的预处理判断,以及方向数组对移动逻辑的简化。时间复杂度为O(nm×4×指令数),空间复杂度为O(nm×4)。优化点在于通过提前检查障碍减少无效扩展,提升搜索效率。

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣654:递归分治的艺术 如何用最大元素构建二叉树

力扣654:递归分治的艺术 如何用最大元素构建二叉树

题目重解我们面对一个看似简单却充满递归魅力的题目:给定一个不含重复元素的整数数组,需要构建一棵特殊的二叉树。这个树的每个父节点都必须是当前子数组中的最大元素,而它的左右子树则分别由该最大值左侧和右侧的...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

2022年蓝桥杯省赛B组扫雷(洛谷P8785)解题全解析:代码+思路+步骤详解

一、题目解读2022年蓝桥杯省赛B组机器人塔(洛谷P8785)是一道经典的算法题目,要求处理在一个二维平面上布置的炸雷与排雷火箭。炸雷具有爆炸半径,当排雷火箭引爆后,会触发周围范围内未被引爆的炸雷,形...

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

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

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

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

发表评论

访客

看不清,换一张

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