华为OD机试真题——天然蓄水库(2025A卷:200分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

news2025/6/5 21:29:36

在这里插入图片描述

2025 A卷 200分 题型

本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!

2025华为OD真题目录+全流程解析/备考攻略/经验分享

华为OD机试真题《天然蓄水库》:


目录

    • 题目名称:天然蓄水库
      • 题目描述
      • 示例
    • Java
      • 题目分析
      • 解决思路
      • Java 代码实现
      • 代码详细解析
      • 综合分析
    • python
      • 题目分析
      • 解决思路
      • Python 代码实现
      • 代码详细解析
      • 关键逻辑图解
      • 综合分析
    • JavaScript
      • 题目分析
      • JavaScript 代码实现
      • 代码详细解析
      • 综合分析
      • 示例测试
        • 示例1:
        • 示例2:
      • 总结
    • C++
      • 解决思路
      • 代码实现
      • 关键步骤解析
      • 正确性验证
    • C语言
      • 解决思路
      • 代码实现
      • 代码详细解析
      • 复杂度与优化
      • 示例测试
    • GO
      • 题目分析
      • Go 代码实现
      • 代码详细解析
      • 示例验证
        • 输入1:
        • 输出1:
      • 时间复杂度与优化
      • 边界处理
      • 综合分析


题目名称:天然蓄水库


  • 知识点:双指针
  • 时间限制:1秒
  • 空间限制:256MB
  • 限定语言:不限

题目描述

公元2919年,人类在X星山脉间建造天然蓄水库,需选取两边界使蓄水量最大。要求:

  1. 山脉用数组s表示,元素为高度。
  2. 边界内的蓄水量为两边界高度的最小值减去中间山脉占用的空间。
  3. 若有多个解,选下标距离最近的边界。
  4. 无法蓄水则输出0,否则输出左、右边界及蓄水量。

输入描述
一行正整数(空格分隔),如 1 9 6 2 5 4 9 3 7,表示s = [1,9,6,2,5,4,9,3,7]

输出描述
若存在合理边界,输出格式为左边界 右边界:蓄水量,如1 6:19;否则输出0

示例

示例1
输入:

1 9 6 2 5 4 9 3 7  

输出:

1 6:19  

说明:选s[1](高9)和s[6](高9),中间蓄水量为3+7+4+5=19

示例2
输入:

3 2 1  

输出:

0  

补充说明

  • 数组长度范围:1 <= length(s) <= 10000
  • 山脉高度范围:0 <= s[i] <= 10000

Java

题目分析

题目要求在给定的山脉数组中选择两个边界,使得它们之间的蓄水量最大。蓄水量计算公式为:两边界高度的最小值 × 区间长度 - 中间山脉的总高度。需要处理以下关键点:

  1. 高效计算:避免暴力枚举所有可能的左右边界(O(n²) 时间复杂度),采用双指针法实现 O(n) 时间复杂度。
  2. 边界条件:处理无法蓄水的情况(结果 ≤ 0)和多个解时选择下标距离最近的边界。
  3. 数据预处理:使用前缀和数组快速计算中间山脉的总高度。

解决思路

  1. 双指针法:初始化左右指针分别指向数组首尾,每次移动较小高度的指针,保留较大高度的边界以探索更大蓄水量。
  2. 前缀和优化:预处理前缀和数组,实现区间和 O(1) 查询。
  3. 条件判断:维护最大蓄水量及对应的左右边界,处理距离更短的解。

Java 代码实现

import java.util.Scanner;

public class Main {
   
    public static void main(String[] args) {
   
        Scanner scanner = new Scanner(System.in);
        String[] parts = scanner.nextLine().trim().split(" ");
        int n = parts.length;
        int[] s = new int[n];
        for (int i = 0; i < n; i++) {
   
            s[i] = Integer.parseInt(parts[i]);
        }

        if (n < 2) {
   
            System.out.println(0);
            return;
        }

        // 预处理前缀和数组,preSum[i] 表示前i个元素的总和
        int[] preSum = new int[n + 1];
        for (int i = 0; i < n; i++) {
   
            preSum[i + 1] = preSum[i] + s[i];
        }

        int left = 0, right = n - 1;
        int maxWater = 0;
        int bestLeft = -1, bestRight = -1;

        while (left < right) {
   
            int minH = Math.min(s[left], s[right]);
            int count = right - left - 1;

            if (count > 0) {
    // 仅当区间内有元素时计算
                int sumMiddle = preSum[right] - preSum[left + 1];
                int water = minH * count - sumMiddle;

                // 更新最大值或更优解(距离更近)
                if (water > maxWater) {
   
                    maxWater = water;
                    bestLeft = left;
                    bestRight = right;
                } else if (water == maxWater) {
   
                    int currentDistance = right - left;
                    int bestDistance = bestRight - bestLeft;
                    if (currentDistance < bestDistance || bestDistance == -1) {
   
                        bestLeft = left;
                        bestRight = right;
                    }
                }
            }

            // 移动较小高度的指针,保留较高边界
            if (s[left] < s[right]) {
   
                left++;
            } else {
   
                right--;
            }
        }

        // 输出结果
        if (maxWater <= 0) {
   
            System.out.println(0);
        } else {
   
            System.out.println(bestLeft + " " + bestRight + ":" + maxWater);
        }
    }
}

代码详细解析

  1. 输入处理

    • 读取输入并转换为整数数组 s
    • 处理长度为 1 的特殊情况(无法形成蓄水区间)。
  2. 前缀和数组

    • preSum[i] 表示前 i 个元素的总和,用于快速计算任意区间和。
  3. 双指针遍历

    • leftright 初始指向数组两端。
    • minH 计算当前左右边界的最小高度。
    • count 表示中间山脉的数量,sumMiddle 通过前缀和数组快速求得。
  4. 蓄水量计算

    • water = minH * count - sumMiddle 直接计算当前区间的蓄水量。
    • 维护 maxWater 和对应的最优边界 bestLeftbestRight
  5. 指针移动策略

    • 移动较小高度的指针,保留较高的边界以探索更大的蓄水量。
  6. 结果输出

    • 根据 maxWater 决定输出格式,处理无效解(结果 ≤ 0)。

综合分析

  1. 时间复杂度:双指针法将时间复杂度从 O(n²) 优化到 O(n),适用于大规模数据(n ≤ 10000)。
  2. 空间复杂度:仅需 O(n) 空间存储前缀和数组。
  3. 正确性保障
    • 前缀和数组确保区间和计算的快速和准确。
    • 指针移动策略保留较高边界,最大化后续探索的潜力。
    • 处理多个解时,优先选择下标距离更近的边界。

python

题目分析

题目要求在给定的山脉数组中选择两个边界,使得它们之间的蓄水量最大。蓄水量计算公式为:两边界高度的最小值 × 区间长度 - 中间山脉的总高度。需要处理以下关键点:

  1. 高效计算:避免暴力枚举所有可能的左右边界(O(n²) 时间复杂度),采用双指针法实现 O(n) 时间复杂度。
  2. 边界条件:处理无法蓄水的情况(结果 ≤ 0)和多个解时选择下标距离最近的边界。
  3. 数据预处理:使用前缀和数组快速计算中间山脉的总高度。

解决思路

  1. 双指针法:初始化左右指针分别指向数组首尾,每次移动较小高度的指针,保留较大高度的边界以探索更大蓄水量。
  2. 前缀和优化:预处理前缀和数组,实现区间和 O(1) 查询。
  3. 条件判断:维护最大蓄水量及对应的左右边界,处理距离更短的解。

Python 代码实现

def main():
    # 读取输入并转换为整数数组
    s = list(map(int, input().strip().split()))
    n = len(s)
    
    # 处理特殊情况:数组长度不足时无法形成蓄水区间
    if n < 2:
        print(0)
        return
    
    # 构建前缀和数组 pre_sum,pre_sum[i] 表示前i个元素的总和
    pre_sum = [0] * (n + 1)
    for i in range(n):
        pre_sum[i + 1] = pre_sum[i] + s[i]
    
    # 初始化双指针和最大值变量
    left, right = 0, n - 1
    max_water = 0
    best_left, best_right = -1, -1
    
    while left < right:
        # 当前左右边界的高度
        min_h = min(s[left], s[right])
        # 中间山脉的数量(区间长度为 right - left - 1)
        count = right - left - 1
        
        if count > 0:  # 仅当区间内有元素时计算蓄水量
            # 计算中间山脉的总高度:前缀和差法
            sum_middle = pre_sum[right] - pre_sum[left + 1]
            # 当前蓄水量 = 容器高度 × 区间长度 - 中间总高度
            current_water = min_h * count - sum_middle
            
            # 如果当前蓄水量更大,更新最大值和最优边界
            if current_water > max_water:
                max_water = current_water
                best_left, best_right = left, right
            # 如果蓄水量相同,但区间更短,则更新最优边界
            elif current_water == max_water:
                current_distance = right - left
                best_distance = best_right - best_left
                if current_distance < best_distance or best_distance == -1:
                    best_left, best_right = left, right
        
        # 移动指针策略:保留较高的边界,移动较矮的一边
        if s[left] < s[right]:
            left += 1</

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

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

相关文章

【Harmony OS】数据存储

目录 数据存储概述 首选项数据存储 关系型数据库 数据存储概述 • 数据存储 是为了解决应用数据持久化问题&#xff0c;使得数据能够存储在外存中&#xff0c;达到保存或共享目的。 • 鸿蒙应用数据存储包括 本地数据存储 和 分布式数据存储 。 • 本地数据存储 为应用…

MybatisPlus--核心功能--service接口

Service接口 基本用法 MyBatisPlus同时也提供了service接口&#xff0c;继承后一些基础的增删改查的service代码&#xff0c;也不需要去书写。 接口名为Iservice&#xff0c;而Iservice也继承了IRepository&#xff0c;这里提供的方法跟BaseMapper相比只多不少&#xff0c;整…

uniapp调试,设置默认展示的toolbar内容

uniapp调试&#xff0c;设置默认展示的toolbar内容 设置pages.json中 pages数组中 json的顺序就可以只需要调整顺序&#xff0c;不会影响该bar在页面中的显示默认展示第一条page

笔记本电脑开机无线网卡自动禁用问题

1.问题环境 电脑品牌&#xff1a;华硕笔记本天选4 电脑型号&#xff1a;FX507VV 电脑系统&#xff1a;windows 11_x64_24h2 文档编写时间&#xff1a;2025年6月 2.问题现象 1. 笔记本电脑开机之后自动禁用无线网卡 使用USB转RJ45转接头同样无效&#xff0c;这个网卡也给禁…

推荐一款使用html开发桌面应用的工具——mixone

简介 mixone是开发桌面应用&#xff08;Win、Mac、Linux&#xff09;的一款工具、其基于electron实现。其拥有简单的工程结构。以为熟悉前端开发的程序员可以很轻松的开发出桌面应用&#xff0c;它比electron的其他框架更简单&#xff0c;因为那些框架基本上还需要了解electro…

【云原生开发】如何通过client-go来操作K8S集群

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

八.MySQL复合查询

一.基本查询回顾 分组统计 group by 函数作用示例语句说明count(*)统计记录条数select deptno, count(*) from emp group by deptno;每个部门有多少人&#xff1f;sum(sal)某字段求和select deptno, sum(sal) from emp group by deptno;每个部门总工资avg(sal)求平均值select…

FastMCP vs MCP:协议标准与实现框架的协同

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…

AI视频“入驻”手机,多模态成智能终端的新战场

文&#xff5c;乐乐 今天&#xff0c;无线蓝牙耳机&#xff08;TWS&#xff09;已经成为人人都用得起的产品。 但退回到9年前&#xff0c;苹果AirPods是全球第一款真正意义上的无线蓝牙耳机。靠着自研并申请专利的Snoop监听技术&#xff0c;苹果解决了蓝牙耳机左右延时和能耗…

nginx+tomcat负载均衡群集

一 案例部署Tomcat 目录 一 案例部署Tomcat 1.案例概述 1.1案例前置知识点 &#xff08;1&#xff09;Tomcat简介 &#xff08;2&#xff09;应用场景 2.实施准备 &#xff08;1&#xff09;关闭Linux防火墙 &#xff08;2&#xff09;安装Java 2.1 安装配置TOMACT …

建造者模式:优雅构建复杂对象

引言 在软件开发中&#xff0c;有时我们需要创建一个由多个部分组成的复杂对象&#xff0c;这些部分可能有不同的变体或配置。如果直接在一个构造函数中设置所有参数&#xff0c;代码会变得难以阅读和维护。当对象构建过程复杂&#xff0c;且需要多个步骤时&#xff0c;我们可…

现场总线结构在楼宇自控系统中的技术要求与实施要点分析

在建筑智能化程度不断提升的当下&#xff0c;楼宇自控系统承担着协调建筑内各类设备高效运行的重任。传统的集中式控制系统在面对复杂建筑环境时&#xff0c;逐渐暴露出布线繁琐、扩展性差、可靠性低等问题。而现场总线结构凭借其分散控制、通信高效等特性&#xff0c;成为楼宇…

学习路之PHP--easyswoole使用视图和模板

学习路之PHP--easyswoole使用视图和模板 一、安装依赖插件二、 实现渲染引擎三、注册渲染引擎四、测试调用写的模板五、优化六、最后补充 一、安装依赖插件 composer require easyswoole/template:1.1.* composer require topthink/think-template相关版本&#xff1a; "…

《云原生安全攻防》-- K8s网络策略:通过NetworkPolicy实现微隔离

默认情况下&#xff0c;K8s集群的网络是没有任何限制的&#xff0c;所有的Pod之间都可以相互访问。这就意味着&#xff0c;一旦攻击者入侵了某个Pod&#xff0c;就能够访问到集群中任意Pod&#xff0c;存在比较大的安全风险。 在本节课程中&#xff0c;我们将详细介绍如何通过N…

06 APP 自动化- H5 元素定位

文章目录 H5 元素定位1、APP 分类2、H5 元素3、H5 元素定位环境的搭建4、代码实现&#xff1a; H5 元素定位 1、APP 分类 1、Android 原生 APP2、混合 APP(Android 原生控件H5页面)3、纯 H5 App 2、H5 元素 H5 元素容器 WebViewWebView 控件实现展示网页 3、H5 元素定位环…

定时线程池失效问题引发的思考

最近在做的一个新功能&#xff0c;在结果探测的时候使用了定时线程池和普通线程池结合&#xff0c;定时线程池周期性创建子任务并往普通线程池提交任务。 问题&#xff1a; 在昨天测试老师发现&#xff0c;业务实际上已经成功了&#xff0c;但是页面还是一直显示进行中。 收到…

AXURE安装+汉化-Windows

安装网站&#xff1a;https://www.axure.com/release-history/rp9 Axure中文汉化包下载地址 链接:https://pan.baidu.com/s/1U62Azk8lkRPBqWAcrJMFew?pwd5418 提取码:5418 下载完成之后&#xff0c;crtlc lang文件夹 到下载的Axure路径下 双击点进这个目录里面。ctrlv把lan…

ArcGIS Pro字段计算器与计算几何不可用,显示灰色

“字段计算器”不可用 如果计算字段命令不可用&#xff0c;请考虑以下可能性&#xff1a; 由 ArcGIS 管理的字段无法手动编辑。因此&#xff0c;无法计算 ObjectID&#xff08;OID 或 FID&#xff09;字段或地理数据库要素类的 Shape_Length 和 Shape_Area 字段的字段值。表中…

mac电脑安装 nvm 报错如何解决

前言 已知&#xff1a;安装nvm成功&#xff1b;终端输入nvm -v 有版本返回 1. 启动全局配置环境变量失败 source ~/.zshrc~ 返回&#xff1a; source: no such file or directory: /Users/你的用户名/.zshrc~2 安装node失败 nvm install 16.13返回&#xff1a; mkdir: /U…

第11节 Node.js 模块系统

为了让Node.js的文件可以相互调用&#xff0c;Node.js提供了一个简单的模块系统。 模块是Node.js 应用程序的基本组成部分&#xff0c;文件和模块是一一对应的。换言之&#xff0c;一个 Node.js 文件就是一个模块&#xff0c;这个文件可能是JavaScript 代码、JSON 或者编译过的…