华为OD机试真题---智能驾驶

华为OD机试中的“智能驾驶”题目是一道涉及广度优先搜索(BFS)算法运用的题目。以下是对该题目的详细解析:

一、题目描述

有一辆汽车需要从m * n的地图的左上角(起点)开往地图的右下角(终点),去往每一个地区都需要消耗一定的油量,加油站可进行加油。请你计算汽车确保从起点到达终点时所需的最少初始油量。

二、地图说明

  • 智能汽车可以上下左右四个方向移动。

  • 地图上的数字取值是0、-1或正整数:

    • -1:表示加油站,可以加满油,汽车的油箱容量最大为100。
    • 0:表示这个地区是障碍物,汽车不能通过。
    • 正整数:表示汽车走过这个地区的耗油量。
  • 如果汽车无论如何都无法到达终点,则返回-1。

三、输入描述

第一行为两个数字M、N,表示地图的大小为M * N(0 < M, N ≤ 200)。后面一个M * N的矩阵,其中的值是0、-1或正整数,加油站的总数不超过200个。

四、输出描述

如果汽车无论如何都无法到达终点,则返回-1;如果汽车可以到达终点,则返回最少的初始油量。

五、解题思路

  1. 状态表示与搜索:使用广度优先搜索(BFS)来遍历地图。需要记录汽车的当前位置(x, y)和当前的剩余油量fuel。同时,使用一个minfuel[x][y]数组来记录到达(x, y)所需的最小初始油量。
  2. 加油站处理:当汽车到达一个加油站(地图值为-1)时,油量将被充满至100。
  3. 油量计算:当从一个点移动到另一个点时,需要根据地图上的数值来增减油量。
  4. 边界与障碍物处理:如果遇到障碍物(地图值为0),该方向将不被考虑。同时需要确保汽车在任何时刻的油量都不为负。

六、具体实现

可以使用队列来实现BFS算法,每次从队列中取出一个节点,并检查它的相邻节点。如果相邻节点是目标节点,则搜索结束;否则,将相邻节点加入队列中。在搜索过程中,需要维护一个maxfuel数组来记录到达每个位置所需的最小初始油量。

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;class State {int x, y, fuel;State(int x, int y, int fuel) {this.x = x;this.y = y;this.fuel = fuel;}
}public class SmartDriving {private static final int MAX_FUEL = 100;private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};/*** 计算到达目的地所需的最小初始燃料量** @param m 表示网格的行数* @param n 表示网格的列数* @param grid 表示网格,其中0表示障碍物,1表示可通过的路径* @return 返回到达目的地所需的最小初始燃料量,如果无法到达则返回-1*/public static int minInitialFuel(int m, int n, int[][] grid) {// 检查起点和终点是否为障碍物,如果是,则无法到达目的地if (grid[0][0] == 0 || grid[m-1][n-1] == 0) {return -1;}// 初始化二分查找的边界int left = 0, right = MAX_FUEL;// 初始化结果为-1,表示无法到达目的地int result = -1;// 使用二分查找确定最小初始燃料量while (left <= right) {// 计算中间值int mid = (left + right) / 2;// 检查当前燃料量是否可以到达目的地if (canReach(grid, m, n, mid)) {// 如果可以到达,更新结果并继续在左侧搜索更小的燃料量result = mid;right = mid - 1;} else {// 如果无法到达,说明燃料量不足,继续在右侧搜索left = mid + 1;}}// 返回最小初始燃料量return result;}/*** 判断是否能够到达目的地** @param grid 二维数组表示的地图,其中-1表示加油站,0表示障碍物,其他正数表示该地点的耗油量* @param m 地图的行数* @param n 地图的列数* @param initialFuel 初始油量* @return 如果能够到达地图的右下角(目的地),返回true;否则返回false*/private static boolean canReach(int[][] grid, int m, int n, int initialFuel) {// 使用队列来实现广度优先搜索Queue<State> queue = new LinkedList<>();// maxFuel数组用于记录到达每个位置时的最大油量int[][] maxFuel = new int[m][n];// 初始化maxFuel数组,所有值设为-1,表示尚未到达for (int[] row : maxFuel) {java.util.Arrays.fill(row, -1);}// 计算初始油量,减去起点的耗油量int startFuel = initialFuel - grid[0][0];// 如果初始油量小于0,则无法开始旅程,返回falseif (startFuel < 0) {return false;}// 如果起点是加油站,初始油量设为最大值if (grid[0][0] == -1) {startFuel = MAX_FUEL;}// 将起点加入队列,并更新到达起点时的最大油量queue.offer(new State(0, 0, startFuel));maxFuel[0][0] = startFuel;// 使用广度优先搜索遍历地图while (!queue.isEmpty()) {// 取出队列头部的状态State state = queue.poll();int x = state.x, y = state.y, fuel = state.fuel;// 如果到达目的地,返回trueif (x == m - 1 && y == n - 1) {return true;}// 遍历四个可能的移动方向for (int[] dir : DIRECTIONS) {int nx = x + dir[0], ny = y + dir[1];// 检查新位置是否有效且不是障碍物if (0 <= nx && nx < m && 0 <= ny && ny < n && grid[nx][ny] != 0) {int newFuel = fuel;// 如果新位置是耗油区域,减少油量if (grid[nx][ny] > 0) {newFuel -= grid[nx][ny];}// 如果新位置是加油站,油量设为最大值if (grid[nx][ny] == -1) {newFuel = MAX_FUEL;}// 如果油量小于0,无法到达新位置,跳过if (newFuel < 0) {continue;}// 如果到达新位置的油量大于之前记录的最大油量,更新最大油量并加入队列if (newFuel > maxFuel[nx][ny]) {maxFuel[nx][ny] = newFuel;queue.offer(new State(nx, ny, newFuel));}}}}// 如果无法到达目的地,返回falsereturn false;}/*** 主函数,用于读取输入并计算最小初始燃料量*/public static void main(String[] args) {// 创建Scanner对象以读取输入Scanner scanner = new Scanner(System.in);// 读取网格的行数int m = scanner.nextInt();// 读取网格的列数int n = scanner.nextInt();// 根据读取的行数和列数创建二维数组int[][] grid = new int[m][n];// 遍历二维数组,读取每个网格单元的值for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = scanner.nextInt();}}// 调用minInitialFuel方法计算最小初始燃料量,并打印结果int result = minInitialFuel(m, n, grid);System.out.println(result);// 关闭Scanner对象scanner.close();}
}

七、测试用例

  1. 测试用例1

输入

2 2
10 20
30 40

输出

70

说明:行走的路线为右->下。

  1. 测试用例2
输入
3 3
0 10 10
10 10 10
10 10 10

输出

-1

说明:起点是障碍物,无法出发。

  1. 测试用例3
输入
4 4
10 30 30 20
30 30 -1 10
0 20 20 40
10 -1 30 40
输出
70

说明:行走的路线为右->右->下->下->下->右。

通过这些测试用例,可以验证算法的正确性和有效性。

在您提供的Java程序中,我们实现了一个智能驾驶系统,该系统能够计算到达地图右下角(目的地)所需的最小初始燃料量。地图由二维数组grid表示,其中每个元素的值代表该位置的耗油量(正数)或是否为加油站(-1表示加油站,不耗油且能将油量补满;0表示障碍物,无法通过)。

八、示例进行解析

输入示例
2 2
10 20
30 40
  • 2 2 表示地图是2行2列的。
  • 接下来的两行数字表示地图的具体内容:
    10 20
    30 40
    
    • 起点在(0, 0),耗油量为10
    • 终点在(1, 1),耗油量为40
    • 从起点到终点只有一条路径,即(0, 0) -> (1, 1)
输出示例
70
解析
  1. 起点油量计算

    • 初始燃料量设为X(我们要找的最小值)。
    • 起点耗油10,因此实际可用燃料为X - 10
  2. 路径耗油

    • (0, 0)(1, 1),需要耗油40(因为终点耗油量为40)。
  3. 燃料量计算

    • 为了让车辆能够到达终点,我们需要满足以下条件:
      • X - 10 >= 40(即初始燃料量减去起点耗油后,仍需足够到达终点的燃料)。
    • 解这个不等式,我们得到X >= 50。但是,由于路径上没有任何加油站,我们需要确保初始燃料量足够覆盖整个路径,并且考虑到起点和终点都是耗油位置,我们需要额外的燃料来确保在到达终点时不会因为油量不足而停下。
    • 实际上,由于只有一条路径且没有加油站,我们需要计算从起点到终点的总耗油量,并加上一定的安全余量(在这个例子中,由于只有一步,所以安全余量就是终点的耗油量)。但是,由于我们的二分查找策略是从0MAX_FUEL(100)进行的,它会自动找到满足条件的最小值。
  4. 二分查找

    • 程序通过二分查找来确定最小初始燃料量。在查找过程中,它会尝试不同的初始燃料量,并使用广度优先搜索(BFS)来检查是否能够到达终点。
    • 在这个例子中,二分查找会发现70是满足条件的最小值,因为:
      • 初始燃料量为70时,起点实际可用燃料为6070 - 10)。
      • 从起点到终点耗油40,剩余20,足够到达终点(尽管实际上在这个简单例子中我们不需要这额外的20燃料,但二分查找策略会确保找到一个安全的最小值)。

九、结论

输出70是正确的,因为它代表了能够确保车辆从起点安全到达终点所需的最小初始燃料量。在这个特定的例子中,由于路径上没有任何加油站,且起点和终点都是耗油位置,因此我们需要确保初始燃料量足够大,以覆盖整个路径并有一定的安全余量。二分查找和广度优先搜索的结合使用有效地找到了这个最小值。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

docker 通过Dockerfile自定义的镜像部署Springboot项目

一、镜像结构介绍&#xff1a; 镜像&#xff1a;层&#xff08;Layer&#xff09;添加安装包、依赖、配置等&#xff0c;每一次操作都形成新的一层&#xff1b;基础镜像&#xff08;BaseImage&#xff09;应用依赖的系统函数库、环境、配置、文件等&#xff1b;入口&#xff0…

全网最早Towards Generalizable Multi-Object Tracking—通用跟踪器的点跟踪CVPR2024

Towards Generalizable Multi-Object Tracking—迈向可推广的多目标跟踪 原标题&#xff1a;Towards Generalizable Multi-Object Tracking 论文链接&#xff1a;https://arxiv.org/pdf/2406.00429 代码链接&#xff1a;https://github.com/qinzheng2000/GeneralTrack.git 作者…

MyBatis框架-动态SQL-XML中的常用标签+特殊字符在XML中的显示

一、if标签、where标签、trim标签、choose标签、set标签、foreach标签 1、问题引入&#xff1a;where关键字和and关键字在动态SQL里面应该如何添加&#xff1f; &#xff08;1&#xff09;if标签&#xff1a; test属性的值是判断条件 if标签里面的内容是条件成立时添加到SQ…

探秘嵌入式位运算:基础与高级技巧

目录 一、位运算基础知识 1.1. 位运算符 1.1.1. 与运算&#xff08;&&#xff09; 1.1.2. 或运算&#xff08;|&#xff09; 1.1.3. 异或运算&#xff08;^&#xff09; 1.1.4. 取反运算&#xff08;~&#xff09; 1.1.5. 双重按位取反运算符&#xff08;~~&#xf…

渗透测试笔记—shodan(7完结)

声明&#xff1a; 学习视频来自B站up主 【泷羽sec】有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&am…

2024年最新版Java八股文复习

最新版本Java八股文复习&#xff0c;每天更新一篇&#xff0c;博主正在持续努力更新中~~~ 一、Java基础篇1、怎么理解面向对象&#xff1f;简单说说封装、继承、多态三大特性&#xff1f;2、多态体现在哪几个方面&#xff1f;3、面向对象的设计原则你知道有哪些吗&#xff1f;4…

Notepad++ 替换所有数字给数字加单引号

前言 今天遇到这样一个场景&#xff1a; 要去更新某张表里 code1,2,3,4,5,6 的数据&#xff0c;把它的 name 设置为 ‘张三’ 但是 code在数据库里面的字段类型是 vachar(64)&#xff0c;它自身携带索引 原本可以这样写 SQL: update tableA set namezhangsan where code in …

前端图像处理(一)

目录 一、上传 1.1、图片转base64 二、图片样式 2.1、图片边框【border-image】 三、Canvas 3.1、把canvas图片上传到服务器 3.2、在canvas中绘制和拖动矩形 3.3、图片(同色区域)点击变色 一、上传 1.1、图片转base64 传统上传&#xff1a; 客户端选择图片&#xf…

推荐一款龙迅HDMI2.0转LVDS芯片 LT6211UX LT6211UXC

龙迅的HDMI2.0转LVDS芯片LT6211UX和LT6211UXC是两款高性能的转换器芯片&#xff0c;它们在功能和应用上有所差异&#xff0c;同时也存在一些共同点。以下是对这两款芯片的详细比较和分析&#xff1a; 一、LT6211UX 主要特性&#xff1a; HDMI2.0至LVDS和MIPI转换器。HDMI2.0输…

51单片机从入门到精通:理论与实践指南入门篇(二)

续51单片机从入门到精通&#xff1a;理论与实践指南&#xff08;一&#xff09;https://blog.csdn.net/speaking_me/article/details/144067372 第一篇总体给大家在&#xff08;全局&#xff09;总体上讲解了一下51单片机&#xff0c;那么接下来几天结束详细讲解&#xff0c;从…

STM32C011开发(3)----Flash操作

STM32C011开发----3.Flash操作 概述硬件准备视频教学样品申请源码下载参考程序生成STM32CUBEMX串口配置堆栈设置串口重定向FLASH数据初始化FLASH 读写演示 概述 STM32C011 系列微控制器内置 Flash 存储器&#xff0c;支持程序存储与数据保存&#xff0c;具备页面擦除、双字写入…

IDEA无法创建java8、11项目创建出的pom.xml为空

主要是由于Spring3.X版本不支持JDK8&#xff0c;JDK11&#xff0c;最低支持JDK17 解决的话要不就换成JDK17以上的版本&#xff0c;但是不太现实 另外可以参考以下方式解决 修改spring初始化服务器地址为阿里云的 https://start.aliyun.com/

【Unity3D】创建自定义字体

前置准备 如图所示&#xff0c;项目工程中需要用文件夹存储0-9的Sprite图片。 使用流程 直接右键存放图片的文件夹&#xff0c;选择【创建自定义字体】&#xff0c;之后会在脚本定义的FontOutputPath中生成材质球和字体。 源码 using System; using System.Collections.Gene…

logminer挖掘日志归档查找问题

--根据发生问题时间点查找归档文件 select first_time,NAME from gv$archived_log where first_time>2016-03-15 17:00:00 and first_time<2016-03-15 21:00:00; 2016-03-15 17:23:55 ARCH/jxdb/archivelog/2016_03_15/thread_1_seq_41588.4060.906577337 2016-03-15 17:…

电商项目高级篇06-缓存

电商项目高级篇06-缓存 1、docker下启动redis2、项目整合redis 缓存 流程图&#xff1a; data cache.load(id);//从缓存加载数据 If(data null){ data db.load(id);//从数据库加载数据 cache.put(id,data);//保存到 cache 中 } return data;在我们的单体项目中可以用Map作…

如何使用GCC手动编译stm32程序

如何不使用任何IDE&#xff08;集成开发环境&#xff09;编译stm32程序? 集成开发环境将编辑器、编译器、链接器、调试器等开发工具集成在一个统一的软件中&#xff0c;使得开发人员可以更加简单、高效地完成软件开发过程。如果我们不使用KEIL,IAR等集成开发环境&#xff0c;…

一个专为云原生环境设计的高性能分布式文件系统

大家好&#xff0c;今天给大家分享一款开源创新的分布式 POSIX 文件系统JuiceFS&#xff0c;旨在解决海量云存储与各类应用平台&#xff08;如大数据、机器学习、人工智能等&#xff09;之间高效对接的问题。 项目介绍 JuiceFS 是一款面向云原生设计的高性能分布式文件系统&am…

Vue-TreeSelect组件最下级隐藏No sub-options

问题&#xff1a;最下级没有数据的话&#xff0c;去除No sub-options信息 为什么没下级&#xff0c;会展示这个&#xff1f; 整个树形结构数据都是由后端构造好返回给前端的。默认子类没数据的话&#xff0c;children是一个空数组。也就是因为这最下级的空数组&#xff0c;导致…

k8s集群增加nfs-subdir-external-provisioner存储类

文章目录 前言一、版本信息二、本机安装nfs组件包三、下载nfs-subdir-external-provisioner配置文件并进行配置1.下载文件2.修改配置 三、进行部署备注&#xff1a;关于镜像无法拉取问题的处理 前言 手里的一台服务器搭建一个单点的k8s集群&#xff0c;然后在本机上使用nfs-su…

C语言数据结构-链表

C语言数据结构-链表 1.单链表1.1概念与结构1.2结点3.2 链表性质1.3链表的打印1.4实现单链表1.4.1 插入1.4.2删除1.4.3查找1.4.4在指定位置之前插入或删除1.4.5在指定位置之后插入或删除1.4.6删除指定位置1.4.7销毁链表 2.链表的分类3.双向链表3.1实现双向链表3.1.1尾插3.1.2头插…