leetcode909:蛇梯棋

news2024/12/12 12:11:31

给你一个大小为 n x n 的整数矩阵 board ,方格按从 1 到 n2 编号,编号遵循 转行交替方式 从左下角开始 (即,从 board[n - 1][0] 开始)的每一行改变方向。

你一开始位于棋盘上的方格  1。每一回合,玩家需要从当前方格 curr 开始出发,按下述要求前进:

  • 选定目标方格 next ,目标方格的编号在范围 [curr + 1, min(curr + 6, n2)] 。
    • 该选择模拟了掷 六面体骰子 的情景,无论棋盘大小如何,玩家最多只能有 6 个目的地。
  • 传送玩家:如果目标方格 next 处存在蛇或梯子,那么玩家会传送到蛇或梯子的目的地。否则,玩家传送到目标方格 next 。 
  • 当玩家到达编号 n2 的方格时,游戏结束。

如果 board[r][c] != -1 ,位于 r 行 c 列的棋盘格中可能存在 “蛇” 或 “梯子”。那个蛇或梯子的目的地将会是 board[r][c]。编号为 1 和 n2 的方格不是任何蛇或梯子的起点。

注意,玩家在每次掷骰的前进过程中最多只能爬过蛇或梯子一次:就算目的地是另一条蛇或梯子的起点,玩家也 不能 继续移动。

  • 举个例子,假设棋盘是 [[-1,4],[-1,3]] ,第一次移动,玩家的目标方格是 2 。那么这个玩家将会顺着梯子到达方格 3 ,但 不能 顺着方格 3 上的梯子前往方格 4 。(简单来说,类似飞行棋,玩家掷出骰子点数后移动对应格数,遇到单向的路径(即梯子或蛇)可以直接跳到路径的终点,但如果多个路径首尾相连,也不能连续跳多个路径)

返回达到编号为 n2 的方格所需的最少掷骰次数,如果不可能,则返回 -1

示例 1:

输入:board = [[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,-1,-1,-1,-1,-1],[-1,35,-1,-1,13,-1],[-1,-1,-1,-1,-1,-1],[-1,15,-1,-1,-1,-1]]
输出:4
解释:
首先,从方格 1 [第 5 行,第 0 列] 开始。 
先决定移动到方格 2 ,并必须爬过梯子移动到到方格 15 。
然后决定移动到方格 17 [第 3 行,第 4 列],必须爬过蛇到方格 13 。
接着决定移动到方格 14 ,且必须通过梯子移动到方格 35 。 
最后决定移动到方格 36 , 游戏结束。 
可以证明需要至少 4 次移动才能到达最后一个方格,所以答案是 4 。 

示例 2:

输入:board = [[-1,-1],[-1,3]]
输出:1

提示:

  • n == board.length == board[i].length
  • 2 <= n <= 20
  • board[i][j] 的值是 -1 或在范围 [1, n2] 内
  • 编号为 1 和 n2 的方格上没有蛇或梯子

步骤1:定义计算问题性质

  1. 输入:

    • 一个大小为 n×nn \times nn×n 的二维整数矩阵 board
    • 矩阵中的每个元素要么是 -1(无蛇或梯子),要么是一个整数,表示目标方格的编号。
    • board[i][j] 表示棋盘第 iii 行第 jjj 列格子的状态。
  2. 输出:

    • 达到编号为 n2n^2n2 的方格所需的最少掷骰次数。如果无法到达,返回 -1
  3. 约束条件:

    • 2≤n≤202 \leq n \leq 202≤n≤20。
    • 每次掷骰子后,玩家最多可以前进 6 格。
    • 蛇和梯子的起点和终点在棋盘上有对应编号。编号 111 和 n2n^2n2 的格子上没有蛇或梯子。
  4. 潜在边界条件:

    • 棋盘上没有蛇或梯子。
    • 棋盘中存在死循环(多个蛇或梯子互相连接)。
    • n=2n = 2n=2 或 n=20n = 20n=20 的极限大小。

步骤2:问题分解与算法设计

1. 将棋盘映射为一维数组
  • 二维矩阵 boardboardboard 的格子编号从左下角开始,转行交替方式编号。
  • 通过一个辅助函数实现编号和坐标的相互映射,便于后续算法处理。
2. 采用广度优先搜索(BFS)
  • 核心思路:
    • BFS 模拟骰子的移动过程,计算从起点 111 到终点 n2n^2n2 的最少步数。
    • BFS 保证了搜索路径中每一步都是最短路径。
  • 步骤:
    1. 从起点 111 开始。
    2. 模拟掷骰子,每次掷骰后计算目标方格(最多前进 6 格)。
    3. 检查目标方格是否有蛇或梯子,更新位置。
    4. 如果到达终点 n2n^2n2,记录步数并返回。
    5. 如果无法继续前进,返回 -1
3. 复杂度分析
  • 时间复杂度:O(n2)O(n^2)O(n2),每个节点最多访问一次。
  • 空间复杂度:O(n2)O(n^2)O(n2),用于存储访问状态。

步骤3:C++代码实现

class Solution {
public:
    // 辅助函数:将二维坐标映射到一维编号
int getId(int row, int col, int n) {
    if (row % 2 == n % 2) {
        return row * n + (n - 1 - col);
    } else {
        return row * n + col;
    }
}

// 主函数:计算最少掷骰次数
int snakesAndLadders(vector<vector<int>>& board) {
    int n = board.size();
    vector<int> flatBoard(n * n + 1, -1); // 将棋盘展平成一维数组
    int id = 1;

    for (int i = n - 1; i >= 0; --i) {
        for (int j = 0; j < n; ++j) {
            int col = (i % 2 == n % 2) ? n - 1 - j : j;
            flatBoard[id++] = board[i][col];
        }
    }

    queue<pair<int, int>> q; // 队列存储(当前位置,步数)
    vector<bool> visited(n * n + 1, false);
    q.push({1, 0}); // 从起点 1 开始
    visited[1] = true;

    while (!q.empty()) {
        auto [curr, steps] = q.front();
        q.pop();

        for (int dice = 1; dice <= 6; ++dice) {
            int next = curr + dice;
            if (next > n * n) break; // 超出棋盘范围

            if (flatBoard[next] != -1) {
                next = flatBoard[next]; // 遇到蛇或梯子
            }

            if (next == n * n) {
                return steps + 1; // 到达终点
            }

            if (!visited[next]) {
                visited[next] = true;
                q.push({next, steps + 1});
            }
        }
    }

    return -1; // 无法到达终点
}

};

步骤4:解题启发

  1. BFS 的优越性:

    • 广度优先搜索在寻找最短路径问题中十分高效,尤其适合树形或图形结构。
    • 在飞行棋或迷宫问题中,BFS 是一个基础且可靠的算法。
  2. 问题分解的重要性:

    • 本题中棋盘的编号映射是核心,分解问题后算法实现更直观。

步骤5:实际应用场景

  1. 应用场景:飞行棋游戏优化

    • 例如:自动驾驶飞行棋 AI 玩家决策。
    • 实现方法:
      • 使用 BFS 预先计算最优路径。
      • 根据当前棋盘状态调整 AI 策略。
  2. 物流调度路径规划

    • 本算法思想可用于模拟物流配送中的路径规划,特别是有额外加速或延迟条件的复杂网络。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2258228.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【特殊子序列 DP】力扣552. 学生出勤记录 II

可以用字符串表示一个学生的出勤记录&#xff0c;其中的每个字符用来标记当天的出勤情况&#xff08;缺勤、迟到、到场&#xff09;。记录中只含下面三种字符&#xff1a; ‘A’&#xff1a;Absent&#xff0c;缺勤 ‘L’&#xff1a;Late&#xff0c;迟到 ‘P’&#xff1a;Pr…

Datawhale AI 冬令营(第一期)定制你的第一个专属模型-学习笔记

最近我报名参加了Datawhale组织的主题为“动手学系列&#xff0c;人人都能应用的AI”的Datawhale AI冬令营&#xff08;第一期&#xff09;。 本次学习一共12天&#xff0c;从12月10日-12月21日&#xff0c;学习会包含【跑通速通手册】&#xff0c;【学习大模型微调&数据集…

【GL009】C/C++总结(一)

自查目录 1. typedef 和 #define 的区别 2. const 、volatile 和 static 的区别 3. const修饰指针 4. 数组指针和指针数组 5. 函数指针和指针函数 6. C/C内存管理 6.1 内存分布图解 6.2 C语言中的内存分配方式 6.3 堆&#xff08;Heap&#xff09;和栈&#xff08;Sta…

opencv库中的函数应用

opencv库中的函数应用 二值化函数功能参数返回值应用例子 自适应二值化函数功能参数返回值应用例子 腐蚀函数功能参数返回值应用例子 膨胀函数功能参数返回值例子 仿射变换函数功能参数返回值例子 透视变换函数功能参数返回值例子 二值化函数 函数&#xff1a;cv2.threshold(i…

HBuilderX(uni-app)Vue3路由传参和接收路由参数!!

uni-app搭建小程序时候Vue3语法接收路由参数&#xff0c;去官方文档查看&#xff0c;是onLoad的option接收参数&#xff0c;我试过&#xff0c;接收不到&#xff0c;上网查各种方法也是不太行&#xff0c;最后自己琢磨出来了&#xff0c;这参数藏得还挺深&#xff01;&#xff…

设置docker镜像加速器

阿里云镜像中心 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 登陆阿里云账号后&#xff0c;可以看到镜像加速器的配置&#xff0c;如下图所示 参考文章地址 Docker 镜像库国内加速的几种方法_docker 加速-CSDN博客

前端成长之路:HTML(3)

在HTML中&#xff0c;有列表标签。列表最大的特点是整齐、简洁、有序&#xff0c;用列表进行布局会更加自由方便。根据使用的情景不同&#xff0c;可以将列表分为三大类&#xff1a;无序列表、有序列表和自定义列表。 无序列表 在HTML中使用<ul>标签定义一个无序列表&a…

【C语言】fscanf 和 fprintf函数

【C语言】fscanf 和 fprintf函数 文章目录 [TOC](文章目录) 前言一、定义二、代码例程三、实验结果四、参考文献总结 前言 使用工具&#xff1a; 1.编译器&#xff1a;DEVC 2.C Primer Plus 第六版-1 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一…

【Vivado】xdc约束文件编写

随手记录一下项目中学到的约束文件编写技巧。 时序约束 创建生成时钟 参考链接&#xff1a; Vivado Design Suite Tcl Command Reference Guide (UG835) Vivado Design Suite User Guide: Using Constraints (UG903) 通过Clocking Wizard IP创建的时钟&#xff08;MMCM或…

从小学题到技术选型哲学:以智能客服系统为例,解读相关AI技术栈20241211

&#x1f9e0;&#x1f4a1;从小学题到技术选型哲学&#xff1a;以智能客服系统为例&#xff0c;解读相关AI技术栈 引言&#xff1a;从小学数学题到技术智慧 &#x1f4da;✨ 在小学数学题中&#xff0c;有这样一道问题&#xff1a; “一个长方形变成平行四边形后&#xff0c…

遥感图像处理二(ENVI5.6 Classic)

1 实验目的和内容 1.1 实验目的 本次上机旨在继续深入了解ENVI软件的基本使用&#xff0c;并对提供的实验数据进行基本的图像分割和地物分类等操作并分析结果。 1.2 实验内容 1.2.1 图像分割 对教材示例数据“C7图像分割”中的风景图、兰花图和娃娃图分别进行图像分割操作…

Xilinx LVDS 接口中的时钟对齐模块的RTL编写

本人写的一个时钟对齐的模块&#xff0c;仅供参考 主要原因&#xff1a; 由于 FPGA 内部布局布线所带来的延时&#xff0c;到达 ISERDESE2 相应管脚的帧时钟、位时 钟与数据信号可能不再保持初始的相位关系&#xff0c;从而导致无法得到正确的串并转换数据&#xff0c;所以需 …

皮带,传送带异物检测识别数据集,2345张图像,yolo,coco,voc标记三种格式的数据集整理

皮带&#xff0c;传送带异物检测识别数据集,2345张图像&#xff0c;yolo&#xff0c;coco&#xff0c;voc标记三种格式的数据集整理 数据集分割 训练组79&#xff05; 1860图片 有效集14% 318图片 测试集7% 167图片 预处理 自动定向&#xff1a; 已应用 调…

sdk环境变量配置后不生效

sdk环境变量配置后 使用adb命令任显示 adb不是内部或外部命令&#xff0c;也不是可运行的程序 或批处理文件。 解决方法&#xff1a;在环境变量的Path中添加platform-tools的地址

JavaEE 【知识改变命运】05 多线程(4)

文章目录 单例模式什么是单例模式饿汉模式懒汉模式多线程- 懒汉模式分析多线程问题第一种添加sychronized的方式第二种添加sychronized的方式改进第二种添加sychronized的方式&#xff08;DCL检查锁&#xff09; 阻塞队列什么是阻塞队列什么是消费生产者模型标准库中的阻塞队列…

RPC设计--从reactor设计 (IOthread)

主从reactor架构 一般的一个网络IO库都是主从reactor模式&#xff0c;即主线程中有一个MainReactor&#xff0c;其负责监听ListenFd&#xff0c;当接受到新的用户连接时&#xff0c;返回的clientfd并不会加入的MainReacotr&#xff0c;而是在子线程&#xff08;这里称为IO线程&…

STM32 出租车计价器系统设计(一) 江科大源码改写

STM32 出租车计价器系统设计 功能目标 驱动步进电机模拟车轮旋转&#xff0c;并实现调速功能。 设置车轮周长和单价&#xff0c;检测车轮转速和运转时间。 计算并显示行驶里程和价格。 硬件材料 28BYJ48 五线四相步进电机和 ULN2003 驱动板模块 测速传感器模块 嵌入式小系统…

威胁驱动的网络安全方法论

摘要 目前的网络安全风险管理实践很大程度上是由合规性要求驱动的&#xff0c;这使得公司/组织不得不在安全控制和漏洞上投入人力/物力。&#xff08;风险管理涉及多个方面&#xff0c;包括资产、威胁、漏洞和控制&#xff0c;并根据事故发生的可能性及造成的影响进行评估。威胁…

AUTOSAR:SOME/IP 概念

文章目录 1. 用例与需求1.1 典型用例1.2 对中间件的要求 2. 协议栈示例3. SOME/IP 概念3.1 中间件整体功能与架构3.2 服务组成元素详细解释 4. 服务发现机制深入剖析5. 总结 1. 用例与需求 1.1 典型用例 信息娱乐系统&#xff1a; 后座娱乐系统连接&#xff1a;允许后排乘客连…

如何将自己的PHP类库发布到composer仓库

将自己的 PHP 类库发布到 Composer 仓库&#xff0c;需要经过一系列的准备和操作步骤&#xff0c;以下是详细说明&#xff1a; 准备工作 创建类库项目&#xff1a;确保你的 PHP 类库项目具有清晰的目录结构&#xff0c;遵循 PSR-4 等 PHP 编码规范。通常&#xff0c;类文件应…