[华为OD]BFS C卷 200 智能驾驶

题目:

有一辆汽车需要从m*n的地图的左上角(起点)开往地图的右下角(终点),去往每一个地区都需 

要消耗一定的油量,加油站可进行加油

请你计算汽车确保从起点到达终点时所需的最少初始油量说明:

(1)智能汽车可以上下左右四个方向移动1

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

-1:表示加油站,可以加满油,汽车的油箱容量最大为100;

0:表示这个地区是障碍物,汽车不能通过

正整数:表示汽车走过这个地区的耗油量

⑶如果汽车无论如何都无法到达终点,则返回-1

输入描述

第一行为两个数字,M, V,表示地图的大小为M,N(0< M,N < 200)

后面一个M*N的矩阵,其中的值是0或-1或正整数,加油站的总数不超过200个

输出描述

如果汽车无论如何都无法到达终点,则返回-1

如果汽车可以到达终点,则返回最少的初始油量

示例1 

输入

2,2 

10,20 

30,40

输出

70

示例2 

输入

4,4 

10,30,30,20 

30,30,-1,10 

0,20,20,40

10,-1,30,40 

输出

70

示例3

输入

4,5

10,0,30,-1,10 

30,0,20,0,20 

10,0,10,0,30 

10,-1,30,0,10 

输出

60

示例4

输入

4,4

10,30,30,20 

30,30,20,10 

10,20,10,40 

10,20,30,40 

输出

-1

题解:这个题目要计算最少初始油料,那么如果经过加油站的话,明显就要直接加满油。

比较明显的BFS题目。但是需要判断到加油站的情况。由于油箱容量100,那么我们出发时候就将当前油量设置为100。

依旧还是需要定义一个内部类,参数有x,y坐标。这个里面就加了,初始油量originalOil,当前坐标走完需要油量needOil,也就是矩阵中当前的值。以及汽车在这个坐标的剩余油量restOil,还有一个bool值,是否有在加油站加过油。

1)如果到加油站时候,车辆没有加过油,那么从出发到这个加油站的初始油量(刚出发时候初始油量)就可以变为100减去当前剩余油量了。

2)当BFS向下一坐标搜索的时候,如果restOil剩余油量不足以满足去下一个坐标需要的油量needOil,那么就继续往下搜索

3)在到终点的时候,如果没有加过油,那么如果剩余油量>0,那么这个路径走下来的初始油量应该可以变成100减去当前剩余油量

4)当走到任意坐标时候,油量足够,而且汽车加过油,那么初始油量应该不变,因为加过油,剩余油量在加油站那个坐标直接变为100了

5)走过一个坐标,那么这个坐标访问标记visit[x][y]=1;

这个里面可以看到有一个难点就是可能有两条路线能经过同一个加油站,两条路径油量不同,如何确保最终是最少油量经过这个加油站。这边采用的是一个map<String,Integer> oilStations来解决表示的是这个加油站坐标和来这个加油站最少得油量。因为在初始化扫描的时候当矩matrixs[i][j]==-1,就是加油站,那么此时就初始化这个加油站油量为Integer.MaxValue.

6)那么在经过加油站的坐标时候,加油站坐标的visit[x][y],还是为0,不能变为1,防止其他路径更少油量,由于visit[x][y]==1,而不能到加油站,结果就不对。此时,先根据oilStations,拿到抵达这个加油站当前的最少油量prsentLeastOil,如果这个路径到这个加油站的最少油量小于

prsentLeastOil,那么说明现在这个路径就更优,那么就把这个路径继续扫描下去,也就是将这个路径的点加入到队列中去。如果大于等于,这条路径就不用继续扫描了,明显不是最优解,不能为等于是因为防止两个加油站相邻,那么等于的话,明显路径会在这两个加油站一直循环扫。

7)用一个列表表示每个到终点的路径最少油量,最后排序取第一个值就是最少初始油量了

这个题感觉难度就在处理加油站的逻辑上面。

代码:

import java.util.*;public class CarPath {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String[] matrix = sc.nextLine().split(",");int m = Integer.valueOf(matrix[0]);int n = Integer.valueOf(matrix[1]);int matrixs[][] = new int[m][n];int visit[][] = new int[m][n];Map<String, Integer> oilStations = new HashMap<>();for (int i = 0; i < m; i++) {String[] data = sc.nextLine().split(",");for (int j = 0; j < n; j++) {matrixs[i][j] = Integer.valueOf(data[j]);visit[i][j] = 0;if (matrixs[i][j] == -1) {oilStations.put(String.valueOf(i) + String.valueOf(j), Integer.MAX_VALUE);}}}int startX = 0;int startY = 0;int endX = m - 1;int endY = n - 1;Path startPath = new Path(startX, startY, matrixs[0][0], 100 - matrixs[0][0]);startPath.originalOil = 100;visit[0][0] = 1;Queue<Path> queue = new LinkedList<>();queue.offer(startPath);List<Integer> needOil = new ArrayList<>();boolean hasRoote = false;int dirctions[][] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};// BFSwhile (!queue.isEmpty()) {Path frontPath = ((LinkedList<Path>) queue).getFirst();if (frontPath.x == endX && frontPath.y == endY) {hasRoote = true;((LinkedList<Path>) queue).pollFirst();continue;}for (int i = 0; i < 4; i++) {int newX = frontPath.x + dirctions[i][0];int newY = frontPath.y + dirctions[i][1];if (newX >= 0 && newX < m && newY >= 0 && newY < n) {System.out.println("newX " + newX + " newY " + newY);if (newX == 3 && newY == 3) {System.out.println("error0");}if (newX == endX && newY == endY) { // 下一个是终点Path endPath = new Path(newX, endY, matrixs[newX][newX], frontPath.getRestOil() - matrixs[newX][newX]);if (endPath.restOil < 0) { // 油不足以走到终点continue;} else {if (frontPath.hasAddOil) { //加过油endPath.originalOil = frontPath.originalOil;} else {//全程没有加过油 并且有多的油endPath.originalOil = frontPath.originalOil - endPath.restOil;}needOil.add(endPath.originalOil);hasRoote = true;queue.offer(endPath);continue;}}if (matrixs[newX][newY] != 0 && matrixs[newX][newY] != -1 && visit[newX][newY] == 0) { //下一个是一般道路Path nextPath = new Path(newX, newY, matrixs[newX][newY],frontPath.getRestOil() - matrixs[newX][newY]);if (nextPath.restOil < 0) { // 油不足以走到终点continue;} else {nextPath.hasAddOil = frontPath.hasAddOil;if (frontPath.hasAddOil) {//加过油nextPath.originalOil = frontPath.originalOil;} else { //没加过油 需要的油就要加上当前道路需要的油nextPath.originalOil = frontPath.originalOil;}}if (nextPath.x == 3 && nextPath.y == 3) {System.out.println("error");}queue.offer(nextPath);visit[newX][newY] = 1;continue;}if (matrixs[newX][newY] == 0) {visit[newX][newY] = 1;continue;}if (matrixs[newX][newY] == -1 && visit[newX][newY] == 0) { // 到加油站了,这个题明显到加油站都得加满油Integer prsentLeastOil = oilStations.get(String.valueOf(newX) + String.valueOf(newY));if (frontPath.restOil >= prsentLeastOil) {continue;}oilStations.put(String.valueOf(newX) + String.valueOf(newY), frontPath.restOil);Path nextPath = new Path(newX, newY, matrixs[newX][newY],100);// 加油站直接加满油nextPath.hasAddOil = true;if (!frontPath.hasAddOil) {// 前面没有加过油nextPath.originalOil = frontPath.originalOil - frontPath.restOil;// 需要的油应该是前车需要的油料减去前车剩余油料,因为初始化是100} else { // 前面已经加过油nextPath.originalOil = frontPath.originalOil;}visit[newX][newY] = 0;  //加油站不设置访问标记 通过判断到加油站剩余油料是最少得来判断是否将当前数据加入队列,继续扫描if (nextPath.x == 3 && nextPath.y == 3) {System.out.println("error1");}queue.offer(nextPath);continue;}}}((LinkedList<Path>) queue).pollFirst(); //首元素推出队列}if (hasRoote) {Collections.sort(needOil);System.out.println(needOil.get(0));} else {System.out.println(-1);}}private static class Path {int x;int y;int needOil;int restOil;int originalOil;boolean hasAddOil;//是否加过油public Path(int x, int y, int needOil) {this.x = x;this.y = y;this.needOil = needOil;}public Path(int x, int y, int needOil, int restOil) {this.x = x;this.y = y;this.needOil = needOil;this.restOil = restOil;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getNeedOil() {return needOil;}public void setNeedOil(int needOil) {this.needOil = needOil;}public int getRestOil() {return restOil;}public void setRestOil(int restOil) {this.restOil = restOil;}public Path(int originalOil) {this.originalOil = originalOil;}public Path(boolean hasAddOil) {this.hasAddOil = hasAddOil;}}
}

验证:

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

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

相关文章

C++ 复习2 输入输出 基本数据类型

输入输出 标准输出流 ( cout ) cout 代表标准输出流&#xff0c;通常用于向屏幕输出数据。 使用操作符 << &#xff08;插入操作符&#xff09;向 cout 发送数据。 例如&#xff0c; std::cout << "Hello, world!" << std::endl; 会在屏幕上打印 …

本地搭建AI环境

本地搭建AI 这几天刚刚看到好兄弟分享的一段关于本地搭建AI的短视频&#xff0c;于是我按照视频里的讲解&#xff0c;进行了实践。感觉非常棒&#xff01;&#xff01;&#xff0c;马上整理成文字与大家分享一下。 在本地启动并运行大型语言模型&#xff0c;运行llama3、phi3…

自然语言处理(NLP)技术有哪些运用?

目录 一、自然语言处理&#xff08;NLP&#xff09;技术有哪些运用&#xff1f; 二、Python进行文本的情感分析 1、NLTK库: 2、TextBlob库: 三、错误排除 一、自然语言处理&#xff08;NLP&#xff09;技术有哪些运用&#xff1f; 自然语言处理&#xff08;NLP&#xff09…

区块链 | NFT 水印:Review on Watermarking Techniques(一)

&#x1f34d;原文&#xff1a;Review on Watermarking Techniques Aiming Authentication of Digital Image Artistic Works Minted as NFTs into Blockchains 1 应用于 NFT 的水印技术 常见的水印技术类型可以分为&#xff1a; 可见 v i s i b l e \mathsf{visible} visi…

循环神经网络(RNN)

大家好&#xff0c;这里是七七&#xff0c;这两天在写关于神经网络相关的知识&#xff0c;面对的是有一定基础的读者哦。 一、RNN核心思想 RNN的核心思想就是曾经的输入造成的影响&#xff0c;会以致影响之后的输入&#xff0c;即隐含层的输出取决于历史数据的全部输入。 三个…

Infuse for Mac激活版:高清影音播放软件

对于热爱影音娱乐的Mac用户来说&#xff0c;Infuse for Mac是一个不容错过的选择。它以其简洁的操作界面和强大的播放功能&#xff0c;为用户带来了全新的影音播放体验。 Infuse for Mac支持广泛的音视频格式&#xff0c;无需额外转换&#xff0c;即可轻松播放您喜爱的影片。无…

Mybatis Plus二级缓存 使用@CacheNamespace 失效@CacheNamespace和@CacheNamespaceRef

1、注解 CacheNamespace(flushInterval 100000,eviction LruCache.class,readWrite false,size 1024)2、xml配置 <cache eviction "LRU" flushInterval "100000" readOnly "true" size "1024"/> 二级缓存&#xff0c;配置文…

【Linux 性能详解】CPU性能分析工具篇

目录 uptime mpstat 实时监控 查看特定CPU核心 pidstart 监控指定进程 组合多个监控类型 监控线程资源 按用户过滤进程 vmstart 用途 基本用法 输出字段 perf execsnoop dstat 通俗解释 技术层面解释 使用示例 总结 uptime uptime 是一个在 Linux 和 Unix…

上班不想用脑子写代码了怎么办?那就试试Baidu Comate啊宝贝

本文目录 前言1、视频编程实战1.1、熟悉代码库中的代码1.2、参考现有代码编写新代码 2、下载使用教程3、使用体验3.1、AutoWork 产品测评3.2、解决有关ajax请求后重定向问题3.3、询问编程相关知识3.3.1、cookie和session的区别与联系3.3.2、数据库中主键外键的相关知识 4、问题…

基于EBAZ4205矿板的图像处理:12图像二值化(阈值可调)

基于EBAZ4205矿板的图像处理&#xff1a;12图像二值化(阈值可调) 我的项目是基于EBAZ4205矿板的阈值可调的图像阈值二值化处理&#xff0c;可以通过按键调整二值化的阈值&#xff0c;key1为阈值加1&#xff0c;key4为阈值减1&#xff0c;key2为阈值加10&#xff0c;key5为阈值…

【bug记录】清除僵尸进程,释放GPU显存

目录 1. 为什么会出现这种情况&#xff1f;2. 解决方案方法一&#xff1a;使用 fuser 命令方法二&#xff1a; 3. 小贴士 在进行深度学习或其他需要GPU支持的任务时&#xff0c;我们有时会发现虽然没有可见的进程在执行&#xff0c;但GPU资源却意外地被占用。这种情况往往会阻碍…

AI换脸原理(4)——人脸对齐(关键点检测)参考文献2DFAN:代码解析

注意,本文属于人脸关键点检测步骤的论文,虽然也在人脸对齐的范畴下。 1、介绍 在本文中,重点介绍了以下几项创新性的成果,旨在为人脸关键点检测领域带来新的突破。 首先,成功构建了一个卓越的2D人脸关键点检测基线模型。这一模型不仅集成了目前最优的关键点检测网络结构,…

sqlite3命令行工具无法退出问题处理

一、背景&#xff1a; 软件使用的后台数据库为sqlite&#xff0c;linux主机系统层面使用sqlite3命令行工具登录数据库后&#xff0c;无法执行sql脚本&#xff0c;无法退出sqlite3。无法执行ctrlc&#xff0c;执行ctrlz后sqlite3前台进程被中断&#xff0c;但是该进程没有退出。…

Spring-依赖查找

依赖查找 根据名称进行查找 实时查找 BeanFactory beanFactory new ClassPathXmlApplicationContext("beans.xml"); Object bean beanFactory.getBean("personHolder"); System.out.println(bean);xml如下: <bean id"person" class&qu…

运维自动化工具:Ansible 概念与模块详解

目录 前言 一、运维自动化工具有哪些 二、Ansible 概述 1、Ansible 概念 2、Ansible 特点 3、Ansible 工作流程 4、Ansible 架构 4.1 Ansible 组成 4.2 Ansible 命令执行来源 5、Ansible 的优缺点 三、Ansible 安装部署 1、环境部署 2、管理节点安装 Ansible 3、…

Golang | Leetcode Golang题解之第75题颜色分类

题目&#xff1a; 题解&#xff1a; func sortColors(nums []int) {p0, p2 : 0, len(nums)-1for i : 0; i < p2; i {for ; i < p2 && nums[i] 2; p2-- {nums[i], nums[p2] nums[p2], nums[i]}if nums[i] 0 {nums[i], nums[p0] nums[p0], nums[i]p0}} }

模型全参数训练和LoRA微调所需显存的分析

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

k8s调度原理以及自定义调度器

kube-scheduler 是 kubernetes 的核心组件之一&#xff0c;主要负责整个集群资源的调度功能&#xff0c;根据特定的调度算法和策略&#xff0c;将 Pod 调度到最优的工作节点上面去&#xff0c;从而更加合理、更加充分的利用集群的资源&#xff0c;这也是我们选择使用 kubernete…

java--io流(一)

1. 前置知识 字符集是什么&#xff1f; 字符集&#xff08;Character Set&#xff09;是一组字符的集合&#xff0c;它定义了可以在计算机系统中使用的所有字符。字符集可以包括字母、数字、标点符号、控制字符、图形符号等。字符集使得计算机能够存储、处理和显示各种语言和…

嵌入式Linux学习第四天启动方式学习

嵌入式Linux学习第四天 今天学习I.MX6U 启动方式详解。I.MX6U有多种启动方式&#xff0c;可以从 SD/EMMC、NAND Flash、QSPI Flash等启动。 启动方式选择 BOOT 的处理过程是发生在 I.MX6U 芯片上电以后&#xff0c;芯片会根据 BOOT_MODE[1:0]的设置来选择 BOOT 方式。BOOT_M…