贪心算法-汽车加油
这道题目描述了一个汽车旅行场景,需要设计一个有效的算法来决定在哪几个加油站停车加油,以便最小化加油次数。题目给出了汽车加满油后的行驶距离n公里,以及沿途若干个加油站的位置。我们需要找出一个方案,使得汽车能够完成整个旅程,同时加油次数最少。
为了更好地理解并解决问题,我们可以将其转化为数学模型和算法设计问题。首先,明确以下几个关键点:
- 汽车的行驶能力:汽车加满油后可以行驶n公里。
- 加油站分布:沿路有k个加油站,每个加油站的具体位置已知。
- 目标:找到一条路线,使得汽车能够完成全程,同时加油次数最少。
解决方案
我们可以使用贪心算法来解决这个问题。贪心策略的基本思想是从局部最优解入手,一步步构造全局最优解。在这里,我们的局部最优决策就是每次选择离当前位置最远的那个加油站作为下一个加油地点。
步骤如下:
-
初始化变量:
- 当前位置设为起点。
- 加油次数计数器置零。
-
迭代过程:
- 遍历所有的加油站,寻找离当前位置最远但又不会超过汽车行驶范围的加油站。
- 如果找到了这样的加油站,就在那里加油,并更新当前位置。
- 同时,加油次数计数器加一。
-
结束条件:
- 如果没有找到合适的加油站,说明当前油量不足以达到任何一个加油站,返回“No Solution”。
- 如果已经到达终点,停止搜索。
实现细节
- 数据结构:可以用一个列表或数组来保存加油站的位置。
- 算法流程:按照上述步骤编写程序逻辑,需要注意的是,在每次选择加油站之后,都要检查是否还能到达下一个加油站,否则就需要再次加油。
注意事项
- 确保加油站的位置是按顺序排列的,这样可以简化查找过程。
- 在实际编码过程中,要注意边界条件的处理,避免出现越界错误。
通过这种方法,我们可以有效地解决这个问题,找到最少加油次数的方案。如果在某一步发现无法前进,那么就表明没有可行的解决方案,此时应返回“No Solution”。
假设我们有一个int[] gasStations
数组,它包含了从起点到终点所有加油站的位置(公里数),并且汽车加满油后能行驶的最大距离为int maxDistance
。我们将从起点开始尝试到达终点,途中尽可能少地加油。
import java.util.Arrays;public class MinimumRefuelStops {public static void main(String[] args) {int maxDistance = 10; // 汽车加满油后能行驶的最大距离int[] gasStations = {2, 5, 7, 10}; // 加油站位置,单位为公里int destination = 10; // 目的地的位置System.out.println(minimumRefuelStops(maxDistance, gasStations, destination));}/*** 计算最少加油次数。** @param maxDistance 汽车加满油后能行驶的最大距离* @param gasStations 加油站位置数组* @param destination 目的地的位置* @return 最少加油次数,若无法到达目的地则返回"No Solution"*/public static String minimumRefuelStops(int maxDistance, int[] gasStations, int destination) {int currentPosition = 0; // 当前位置int refuelCount = 0; // 加油次数int nextStationIndex = 0; // 下一个加油站的索引while (currentPosition < destination) {// 找到最远可以到达的加油站while (nextStationIndex < gasStations.length && gasStations[nextStationIndex] <= currentPosition + maxDistance) {nextStationIndex++;}// 如果当前位置已经超过了最后一个加油站,但仍未到达目的地if (nextStationIndex == gasStations.length && currentPosition + maxDistance < destination) {return "No Solution";}// 如果当前位置已经可以到达或超过目的地if (currentPosition + maxDistance >= destination) {break;}// 如果有可用的加油站,选择最远的一个加油if (nextStationIndex > 0) {currentPosition = gasStations[nextStationIndex - 1];refuelCount++;} else {// 没有可以到达的加油站return "No Solution";}}return String.valueOf(refuelCount);}
}
这段代码中,我们定义了一个minimumRefuelStops
方法来计算最少加油次数。该方法首先初始化当前位置和加油次数,然后在一个循环中不断寻找最远可以到达的下一个加油站,直到汽车能够到达目的地或者确定无法到达目的地为止。
注意,这个例子假设了gasStations
数组中的元素已经按照从小到大的顺序排序,这是合理的,因为加油站的位置应该是沿着路径递增的。如果实际情况不是这样,您可能需要先对gasStations
数组进行排序。
在每次决定是否加油时,贪心算法会选择在当前油量不足以到达下一个加油站或目的地时才进行加油。这种选择保证了每次加油都是必要的,避免了不必要的加油操作,从而减少了总的加油次数。
package tanxin;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;public class CarsStop {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt(); // 输入加满油可行驶的公里数int k = scanner.nextInt(); // 输入加油站数量int[] distances = new int[k + 1]; // 定义数组存储相邻加油站之间的距离,最后一个元素是最后一个加油站到目的地的距离for (int i = 0; i < k; i++) {distances[i] = scanner.nextInt(); // 读取相邻加油站之间的距离}distances[k] = scanner.nextInt(); // 最后一个加油站到目的地的距离int m = 0; // 初始化加油次数为0int t = n; // 汽车开始可行驶的公里数List<Integer> stations = new ArrayList<>(); // 存储加油的加油站编号for (int i = 0; i <= k; i++) { // 包括最后一个加油站到目的地的距离if (distances[i] > n) { // 如果某段距离大于汽车的最大行驶距离,输出无解并退出程序System.out.println("No Solution");return;}if (t < distances[i]) { // 如果当前剩余油量不足以到达下一个地点,则需要加油t = n; // 汽车加一次油,汽车能行驶的距离变为nm++; // 加油次数+1stations.add(i - 1); // 记录加油的加油站编号,注意这里是i-1因为是在到达i站之前加油}t -= distances[i]; // 减去已行驶的距离}System.out.println("加油次数为:" + m); // 输出加油次数if (!stations.isEmpty()) {System.out.print("加油地点:");for (Integer station : stations) {System.out.print("第" + (station + 1) + "个加油站, ");}System.out.println(); // 换行}}
}
-
输入读取:
- 首先,程序通过
Scanner
类读取用户输入的数据。包括汽车加满油后可以行驶的最大距离n
和加油站的数量k
。 - 然后,程序读取每个加油站之间的距离(存入
distances
数组),以及最后一个加油站到目的地的距离。
- 首先,程序通过
-
初始化变量:
m
变量用于记录加油次数,初始值为0。t
变量代表汽车当前还剩多少公里可以行驶,初始值为n
,即汽车加满油后的最大行驶距离。stations
列表用来存储每次加油时所在的加油站编号。
-
核心逻辑:
- 使用一个循环遍历所有加油站的距离数据,包括从最后一个加油站到目的地的距离。
- 对于每一个距离
distances[i]
,首先检查该距离是否超过了汽车的最大行驶距离n
,如果是,则输出“无解”并结束程序。 - 接着,判断当前剩余油量
t
是否足够行驶至下一个加油站或目的地。如果不够,则需要在当前加油站加油,并更新相关变量:- 将
t
重置为n
,表示汽车加满油后能行驶的最大距离。 - 增加加油次数
m
。 - 记录加油的加油站编号
i - 1
到stations
列表中(注意这里是因为加油是在到达下一个加油站之前完成的)。
- 将
- 更新
t
,减去已经行驶过的距离distances[i]
。
-
输出结果:
- 循环结束后,输出总的加油次数
m
。 - 如果有加油记录,还会输出具体的加油地点。
- 循环结束后,输出总的加油次数
示例运行
假设输入如下:
7 7
1 2 3 4 5 1 6 1
这表示汽车加满油后可以行驶的最大距离为7公里,总共有7个加油站,各加油站间的距离分别为1, 2, 3, 4, 5, 1公里,最后一个加油站到目的地的距离为6公里。
相关文章:

贪心算法-汽车加油
这道题目描述了一个汽车旅行场景,需要设计一个有效的算法来决定在哪几个加油站停车加油,以便最小化加油次数。题目给出了汽车加满油后的行驶距离n公里,以及沿途若干个加油站的位置。我们需要找出一个方案,使得汽车能够完成整个旅程…...

Qt信号和槽-->day04
Qt信号和槽 标准的信号和槽函数Qt中的槽函数Qt中的信号 connect案例 自定义信号和槽案例分析 信号槽的拓展信号连接信号案例 信号槽的两种连接方式Qt5中的处理方式Qt4中的处理方式Qt5处理信号槽重载问题案例 lambda表达式简单案例Qt中的应用 补充知识点 标准的信号和槽函数 QW…...

【Linux】为终端命令自定义快件键并弹窗提醒 设置快捷键切换网络代理(Network Proxy)Disabled/Manual 并弹窗提醒
【Linux】为终端命令自定义快件键并弹窗提醒 设置快捷键切换网络代理(Network Proxy)Disabled/Manual 并弹窗提醒 可以自定义快捷键执行终端命令,执行完毕会有弹窗提醒。下面给一个例子,设置快捷键切换网络代理(Netwo…...
十六:Spring Boot依赖 (1)-- spring-boot-starter 依赖详解
1. 简介: spring-boot-starter 是 Spring Boot 项目中的基础启动器依赖,它为开发者提供了 Spring Boot 应用所需的核心功能和自动配置 spring-boot-starter 不是一个具体的功能模块,而是一个基础的启动器。 Spring Boot 提供了一系列的 sta…...

讲讲关于SNMP与智能PDU插座
什么是SNMP 简单网络管理协议 (SNMP) 是一种应用层协议,主要用于网络管理中的设备监控和控制。通过 SNMP,网络管理员可以从管理站远程访问网络中的设备,获取设备的状态信息、配置参数,甚至控制设备的行为。SNMP 被广泛应用于 TCP/…...
在CentOS下安装RabbitMQ
在CentOS下安装RabbitMQ 在CentOS下安装RabbitMQ可以按照以下步骤进行:步骤 1: 更新系统步骤 2: 安装Erlang步骤 3: 添加RabbitMQ仓库步骤 4: 安装RabbitMQ步骤 5: 启动RabbitMQ服务步骤 6: 检查RabbitMQ状态步骤 7: 启用RabbitMQ管理插件(可选ÿ…...

前端使用Canvas实现网页电子签名(兼容移动端和PC端)
实现效果: 要使用Canvas实现移动端网页电子签名,可以按照以下步骤: 在HTML文件中创建一个Canvas元素,并设置其宽度和高度,以适配移动设备的屏幕大小。 // 创建一个canvas元素 let canvas document.createElement(&q…...
什么是OSTRPT报文?
OSTRPT(Order Status Report)是一种 EDI(电子数据交换)报文,用于在供应链管理中向采购商报告订单状态。这种报文通常由供应商发送给采购商,目的是告知订单的当前处理状态、预期交货时间、订单中的变化等信息…...

PICO+Unity MR空间锚点
官方链接:空间锚点 | PICO 开发者平台 注意:该功能只能打包成APK在PICO 4 Ultra上真机运行,无法通过串流或PICO developer center在PC上运行。使用之前要开启视频透视。 在 Inspector 窗口中的 PXR_Manager (Script) 面板上,勾选…...
electron 中 contextBridge 作用
1. 安全地实现渲染进程和主进程之间的通信 在 Electron 应用中,主进程和渲染进程是相互隔离的,这是为了安全和稳定性考虑。 然而,在很多情况下,渲染进程需要访问主进程中的某些功能,例如系统级别的操作或者一些应用级…...
15分钟学 Go 第 42 天:RESTful API设计
第42天:RESTful API设计 目标:理解RESTful API的设计原则 在现代Web开发中,RESTful API(Representational State Transfer)已经成为了标准的架构风格,用于实现客户端与服务器之间的通信。通过遵循REST的设…...

如何安全的中断一个运行中的线程?
文心快码进入3.0时代, 最新发布的代码问答、编码、Debug、单测、安全智能体, 分别在开发的设计、编码、构建、测试验证全流程通过AI赋能,让效率更高、效果更好。可以通过自然语言对话,独立为你完成一项编码任务。 👉点…...
【121. 买卖股票的最佳时机】——贪心算法/动态规划
121. 买卖股票的最佳时机 一、题目难度 简单 三、题目描述 给定一个数组 prices,它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择某一天买入这只股票,并选择在未来的某一个不同的日子卖出该股票。设计一个算法来计算你所能获…...
LLMs之Calculate:利用大语言模型技术基于文本内容实现数字计算能力的简介、常用方法、代码实现之详细攻略
LLMs之Calculate:利用大语言模型技术基于文本内容实现数字计算能力的简介、常用方法、代码实现之详细攻略 导读:在基于大语言模型(LLM)技术实现数字计算能力的背景下,文本内容的理解和计算过程涉及多个领域的交叉技术,包括自然语言处理(NLP)、机器学习、以及数值计算。…...
LeetCode题练习与总结:判断子序列--392
一、题目描述 给定字符串 s 和 t ,判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一…...

json数据结构的转换
# json可用于赌徒与原件数据的转换(json以字符串的形式储存数据,在通过json进行两种语言的转换时,应先将数据类型转换成列表或字典,再由列表或字典转换成json字符串,最后由json字符串转换成另一种语言的列表或字典数据…...
mysql删除语句:@Update(“TRUNCATE TABLE employee“)讲解
这个 SQL 语句: TRUNCATE TABLE employee是一个 SQL DDL(数据定义语言) 操作,用于清空数据库表中的所有记录,但不会删除表结构(即列和索引等)。 逐部分解释: TRUNCATE:…...
如何修改浏览器指纹?
网络安全日益重要,我们的上网行为变得越来越容易被追踪和分析。其中,浏览器指纹就是一种强大的技术手段,它可以说是你上网的身份象征。 一、浏览器指纹是什么 浏览器指纹是网站和在线平台用来收集关于你的浏览器、设备和网络的详细信息的一…...

实现3D热力图
实现思路 首先是需要用canvas绘制一个2D的热力图,如果你还不会,请看json绘制热力图。使用Threejs中的canvas贴图,将贴图贴在PlaneGeometry平面上。使用着色器材质,更具json中的数据让平面模型 拔地而起。使用Threejs内置的TWEEN&…...
GEE ui界面实现:用户自画多边形, 按面积比例在多边形中自动生成样点,导出多边形和样点shp,以及删除上一组多边形和样点(有视频效果展示)
零、背景 这几天在选样点,发现GEE有强大的ui功能,于是应用在我的工作上。 下述代码实现了几个功能: ①用户可以自己勾勒多边形,随后程序会按面积比例在多边形中自动生成样点,同时根据改多边形的区域生成区域平均月N…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
什么是EULA和DPA
文章目录 EULA(End User License Agreement)DPA(Data Protection Agreement)一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA(End User License Agreement) 定义: EULA即…...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
NPOI操作EXCEL文件 ——CAD C# 二次开发
缺点:dll.版本容易加载错误。CAD加载插件时,没有加载所有类库。插件运行过程中用到某个类库,会从CAD的安装目录找,找不到就报错了。 【方案2】让CAD在加载过程中把类库加载到内存 【方案3】是发现缺少了哪个库,就用插件程序加载进…...
OD 算法题 B卷【正整数到Excel编号之间的转换】
文章目录 正整数到Excel编号之间的转换 正整数到Excel编号之间的转换 excel的列编号是这样的:a b c … z aa ab ac… az ba bb bc…yz za zb zc …zz aaa aab aac…; 分别代表以下的编号1 2 3 … 26 27 28 29… 52 53 54 55… 676 677 678 679 … 702 703 704 705;…...
鸿蒙HarmonyOS 5军旗小游戏实现指南
1. 项目概述 本军旗小游戏基于鸿蒙HarmonyOS 5开发,采用DevEco Studio实现,包含完整的游戏逻辑和UI界面。 2. 项目结构 /src/main/java/com/example/militarychess/├── MainAbilitySlice.java // 主界面├── GameView.java // 游戏核…...