BFS解决最短路问题(4)_为高尔夫比赛砍树

news2024/10/28 22:34:47

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

BFS解决最短路问题(4)_为高尔夫比赛砍树

收录于专栏【经典算法练习】
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌
   

目录

1. 题目链接

2. 题目描述

3. 解法

算法思路:

代码展示:

4. 算法总结 


1. 题目链接

OJ链接 : 为高尔夫比赛砍树

2. 题目描述

你被请来给一个要举办高尔夫比赛的树林砍树。树林由一个 m x n 的矩阵表示, 在这个矩阵中:

  • 0 表示障碍,无法触碰
  • 1 表示地面,可以行走
  • 比 1 大的数 表示有树的单元格,可以行走,数值表示树的高度

每一步,你都可以向上、下、左、右四个方向之一移动一个单位,如果你站的地方有一棵树,那么你可以决定是否要砍倒它。

你需要按照树的高度从低向高砍掉所有的树,每砍过一颗树,该单元格的值变为 1(即变为地面)。

你将从 (0, 0) 点开始工作,返回你砍完所有树需要走的最小步数。 如果你无法砍完所有的树,返回 -1 。

可以保证的是,没有两棵树的高度是相同的,并且你至少需要砍倒一棵树。

示例 1:

输入:forest = [[1,2,3],[0,0,4],[7,6,5]]
输出:6
解释:沿着上面的路径,你可以用 6 步,按从最矮到最高的顺序砍掉这些树。

示例 2:

输入:forest = [[1,2,3],[0,0,0],[7,6,5]]
输出:-1
解释:由于中间一行被障碍阻塞,无法访问最下面一行中的树。

示例 3:

输入:forest = [[2,3,4],[0,0,5],[8,7,6]]
输出:6
解释:可以按与示例 1 相同的路径来砍掉所有的树。
(0,0) 位置的树,可以直接砍去,不用算步数。

提示:

  • m == forest.length
  • n == forest[i].length
  • 1 <= m, n <= 50
  • 0 <= forest[i][j] <= 109

3. 解法

算法思路:

1. 先找出砍树的顺序

2. 然后按照砍树的顺序, 一个一个的用bfs求出最短路即可.

1. 准备阶段
数据结构的准备:首先定义 m 和 n 来存储森林的行数和列数,使用 vector<pair<int, int>> 来保存所有需要砍伐的树的位置。
找到树木的位置:遍历整个森林,将所有树木(高度大于1的元素)的位置存储到 trees 向量中。

2. 排序
按照高度排序:对 trees 向量进行排序,使得树木按照高度升序排列。使用 std::sort 和一个自定义的比较函数,根据森林中树的高度来排序。

3. 砍树过程
初始化砍树的起始位置:起始位置为(0, 0),即森林的左上角。
循环砍伐树木:对于每棵树,调用 bfs 函数来计算从当前的位置到目标树的位置的最短路径。
如果路径不存在(返回 - 1),则直接返回 - 1。
如果路径存在,将步数累加到结果 ret 中,并更新当前的位置。

4. BFS搜索
BFS算法:在 bfs 函数中实现宽度优先搜索(BFS)来寻找从当前树的位置到目标树的位置的最短路径。
初始化:使用一个队列存储当前的搜索状态,使用 memset 清空访问记录 vis。
搜索过程:
进行层次遍历,逐步向四个方向扩展(上下左右),检查每一个可移动的点。
如果遇到目标树的位置,直接返回当前的步数。
如果队列为空且未找到目标,则返回 - 1。 

代码展示:

class Solution {
    int m, n;
public:
    int cutOffTree(vector<vector<int>>& forest) 
    {
        m = forest.size(), n = forest[0].size();
        //1. 准备工作, 找出砍树的顺序
        vector<pair<int, int>> trees;
        for(int i = 0; i < m; i++)
            for(int j = 0; j < n; j++)
                if(forest[i][j] > 1) trees.push_back({i, j});

        sort(trees.begin(), trees.end(), [&](const pair<int, int>& p1, const pair<int, int>& p2)
        {
            return forest[p1.first][p1.second] < forest[p2.first][p2.second];
        });

        //2. 按照顺序砍树
        int bx = 0, by = 0;
        int ret = 0;
        for(auto& [a, b] : trees)
        {
            int step = bfs(forest, bx, by, a, b);
            if(step == -1) return -1;
            ret += step;
            bx = a, by = b;
        }
        return ret;
    }
    bool vis[51][51];
    int dx[4] = {0, 0, 1, -1};
    int dy[4] = {1, -1, 0, 0};
    
    int bfs(vector<vector<int>>& forest, int bx, int by, int ex, int ey)
    {
        if(bx == ex && by == ey) return 0;

        queue<pair<int, int>> q;
        memset(vis, 0, sizeof vis);
        q.push({bx, by});
        vis[bx][by] = true;

        int step = 0;
        while(q.size())
        {
            step++;
            int sz = q.size();
            while(sz--)
            {
                auto [a, b] = q.front();
                q.pop();
                for(int i = 0; i < 4; i++)
                {
                    int x = a + dx[i], y = b + dy[i];
                    if(x >= 0 && x < m && y >= 0 && y < n && forest[x][y] && !vis[x][y])
                    {
                        if(x == ex && y == ey) return step;
                        q.push({x, y});
                        vis[x][y] = true; 
                    }
                }
            }
        }
        return -1;
    }
};

 

4. 算法总结 

时间复杂度
遍历森林的复杂度为 O(m * n),而排序树木的复杂度为 O(k log k)(k为树的数量)。
BFS搜索的最坏情况复杂度为 O(m * n),因为每个位置最多被访问一次。
整体复杂度为 O(m * n + k log k)。
空间复杂度
使用了 O(m * n) 的空间来存储访问标记和队列,整体空间复杂度也是 O(m * n)。
总结
该算法通过将树木按高度排序,并使用 BFS 逐步计算每棵树之间的最短路径,从而确保在每一步都能按照要求的顺序砍伐树木。BFS 保证了路径的最短性,而排序确保了树木被砍伐的顺序正确。 

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

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

相关文章

LeetCode-684. 冗余连接

. - 力扣&#xff08;LeetCode&#xff09; 题目 树可以看成是一个连通且 无环 的 无向 图。 给定往一棵 n 个节点 (节点值 1&#xff5e;n) 的树中添加一条边后的图。添加的边的两个顶点包含在 1 到 n 中间&#xff0c;且这条附加的边不属于树中已存在的边。图的信息记录于…

传输层UDP

再谈端口号 端口号&#xff1a;标识了主机上进行通信的不同的应用程序 在TCP/IP 协议中我们用“源IP”"源端口号" “目的IP”“目的端口号” “协议号”五元组来标识一个通信 用netstat -n 查看 查看网络信息&#xff0c;我们有两种命令查看网络通信1.用netsta…

Python | Leetcode Python题解之第509题斐波那契数

题目&#xff1a; 题解&#xff1a; class Solution:def fib(self, n: int) -> int:if n < 2:return nq [[1, 1], [1, 0]]res self.matrix_pow(q, n - 1)return res[0][0]def matrix_pow(self, a: List[List[int]], n: int) -> List[List[int]]:ret [[1, 0], [0, …

1 环境配置、创建功能包、编译、Cmake文件及package文件学习笔记

1 基本结构 放张 赵虚左老师的pdf截图 2 环境配置 //每次都需配置 . install/setup.bash//或者一次配置echo "source /path/to/your/workspace_name/install/setup.bash" >> ~/.bashrcsource ~/.bashrc3 创建功能包 ros2 pkg create 包名--build-type 构建类…

气象监测软件的程序设计

老师留了个作业&#xff0c;感觉挺有意思&#xff0c;记录一下 文章目录 气象监测软件的程序设计项目指导书&#xff08;一&#xff09;基本信息&#xff08;二&#xff09;项目目标&#xff08;三&#xff09;任务描述&#xff08;四&#xff09;指导内容任务 1&#xff1a;根…

电磁干扰(EMI)与电磁兼容性(EMC)【小登培训】

电磁干扰&#xff08;EMI&#xff09;和电磁兼容性&#xff08;EMC&#xff09;是每个产品在3C &#xff0c;CE认证过程中必不可少的测试项目&#xff1a; 一、电磁干扰&#xff08;EMI&#xff09; EMI&#xff08;Electromagnetic Interference&#xff09;是指电子设备在工作…

ARM学习(33)英飞凌(infineon)PSOC 6 板子学习

笔者来聊一下psoc62 系列板子的知识 1、PSOC62板子介绍 Psoc6-evaluationkit-062S2 与RT-Thread联合推出的一款32位的双core的板子&#xff0c;基于CortexM4以及CortexM0。 管脚兼容Arduio。板载DAP-Link&#xff0c;可以支持调试以及串口&#xff0c;无需外接2MB的Flash以及…

JavaEE初阶---文件IO总结

文章目录 1.文件初识2.java针对于文件的操作2.1文件系统的操作---file类2.2文件内容的操作---流对象的分类2.4字符流的操作》文本文件2.4.1异常的说明2.4.2第一种文件内容的读取方式2.4.3第二种读取方式2.4.4close的方法的介绍2.4.5close的使用优化操作2.4.6内容的写入 2.3字节…

数据结构与算法汇总整理篇——数组与字符串双指针与滑动窗口的联系学习及框架思考

数组 数组精髓&#xff1a;循环不变量原则 数组是存放在连续内存空间上的相同类型数据的集合&#xff0c;通过索引(下标)访问元素&#xff0c;索引从0开始 随机访问快(O(1)时间复杂度)&#xff1b;插入删除慢(需要移动元素)&#xff1b;长度固定(部分语言中可动态调整) 其存…

【CSS】边界三角形

有三角形 Unicode 字符。您可以在 SVG 中绘制三角形。但还有另一种在 Web 上绘制三角形的方法&#xff0c;只需使用 border 属性和一些 CSS 技巧即可。 想象一个具有粗边框的元素&#xff1a; .triangle {width: 200px;height: 200px;border: 10px solid black; }现在想象一下…

公园客流统计系统根据游客数量安排清洁人员

公园作为人们休闲娱乐的公共场所&#xff0c;游客流量时常处于动态变化中。而公园客流统计系统的应用&#xff0c;为依据游客数量合理安排清洁人员提供了有效途径&#xff0c;主要体现在以下几个方面。 一、精准掌握游客分布&#xff0c;按需调配清洁力量 公园客流统计系统能够…

Es可视化界面 ElasticHd

前言 在开发的过程中&#xff0c;有一个可视化界面工具&#xff0c;以及一个可执行的es相关语句的工具十分重要&#xff0c;主要有以下这些 1. Kibana‌&#xff1a;○ Kibana是Elastic官方提供的数据可视化工具&#xff0c;功能强大&#xff0c;支持多种图表类型&#xff0c…

REST APIs与微服务:关键差异

在构建基于微服务的应用程序时RESYful API和微服务这两个术语经常相伴出现。然而&#xff0c;它们指的是截然不同的东西。 了解 RESTful API 和微服务之间差异的最简单方式是这样&#xff1a; 微服务&#xff1a;它们是构成更大规模基于微服务的应用程序的单个服务和功能&…

雷池社区版OPEN API使用教程

OPEN API使用教程 新版本接口支持API Token鉴权 接口文档官方没有提供&#xff0c;有需要可以自行爬取&#xff0c;爬了几个&#xff0c;其实也很方便 使用条件 需要使用默认的 admin 用户登录才可见此功能版本需要 > 6.6.0 使用方法 1.在系统管理创建API TOKEN 2.发…

参会记录|2024 中国计算机大会(CNCC 2024)

前言&#xff1a;2024年10月24-26日&#xff0c;有幸在横店参加了2024年度的中国计算机大会&#xff08;CNCC&#xff09;&#xff0c;本篇博客总结本人在会议期间收听的主要报告内容及收获。 2024.10.24 上午 夏苑海岳开襟 如何实现人工智能在现实场景中的落地&#xff1f; …

解锁V2G:电动汽车如何化身电网“充电宝”,最重要的是将成为一种赚钱的方式!

解锁V2G&#xff1a;电动汽车如何化身电网“充电宝” 随着新能源汽车的普及&#xff0c;电动汽车不仅仅是交通工具&#xff0c;还能成为电网的重要补充。今天&#xff0c;我们来聊聊V2G&#xff08;Vehicle-to-Grid&#xff09;技术&#xff0c;看看它是如何实现车辆与电网之间…

Git相关介绍

基本概念 关注&#xff08;watch&#xff09; 关注项目&#xff0c;当项目更新可以接收到通知 事物卡片&#xff08;Issue&#xff09; 发现代码BUG&#xff0c;但是目前没有成型代码&#xff0c;需要讨论时用 Git工作区域 工作区 添加、编辑、修改文件等动作 暂存区 …

蓝海创意云入选中国夏衍电影学会工业与科技影视专业委员会成员单位

党的二十届三中全会指出&#xff0c;科技自立自强是中国式现代化的有力保障。科技兴则民族兴&#xff0c;科技强则国家强。为深入的贯彻落实这一重要部署&#xff0c;推动工业与科技领域的融合发展充分发挥电影艺术在传播科技创新精神、展现工业发展成就方面的独特作用&#xf…

【AI大模型】使用谷歌 Gemini API 构建自己的 ChatGPT(二)

上一篇文章 【AI大模型】使用谷歌 Gemini API 构建自己的 ChatGPT&#xff08;一&#xff09;&#x1f680;我们介绍了 Gemini 是什么&#xff0c;以及如何使用Gemini 构建一个多模态的聊天场景示例。这一篇我们使用 langchain 与 Gemini 集成构建应用&#xff1a; 将 Langcha…

C/C++:WinSock_TCP通信实例

一、socket函数 第一种使用socket函数来创建套接字&#xff0c;函数调用成功将返回套接字句柄。 socket函数接收三个参数。af 、type 、protocol af&#xff1a;指定套接字使用的地址格式。 type&#xff1a;指定套接字的类型。 protocol&#xff1a;配合type参数使用&#xf…