华为OD机考双机位C卷 - 天然蓄水库 (Java & Python & JS & GO & C++ & C)

天然蓄水库

2026华为OD机试双机位C卷 - 华为OD上机考试双机位C卷

华为OD机试双机位C卷真题目录点击查看: 【全网首发】2026华为OD机位C卷 机考真题题库含考点说明以及在线OJ(OD上机考试双机位C卷)

题目描述

公元2919年,人类终于发现了一颗宜居星球——X星。
现想在X星一片连绵起伏的山脉间建一个天热蓄水库,如何选取水库边界,使蓄水量最大?

要求:

  • 山脉用正整数数组s表示,每个元素代表山脉的高度。

  • 选取山脉上两个点作为蓄水库的边界,则边界内的区域可以蓄水,蓄水量需排除山脉占用的空间

  • 蓄水量的高度为两边界的最小值。

  • 如果出现多个满足条件的边界,应选取距离最近的一组边界。

输出边界下标(从0开始)和最大蓄水量;如果无法蓄水,则返回0,此时不返回边界。
例如,当山脉为s=[3,1,2]时,则选取s[0]和s[2]作为水库边界,则蓄水量为1,此时输出:0 2:1
当山脉s=[3,2,1]时,不存在合理的边界,此时输出:0。

输入描述

一行正整数,用空格隔开,例如输入

1 2 3

表示s=[1,2,3]

输出描述

当存在合理的水库边界时,输出左边界、空格、右边界、英文冒号、蓄水量;例如

0 2:1

当不存在合理的书库边界时,输出0;例如

0

备注

  • 1 ≤ length(s) ≤ 10000

  • 0 ≤ s[i] ≤ 10000

示例1

输入

1 9 6 2 5 4 9 3 7

输出

1 6:19

说明

经过分析,选取s[1]和s[6],水库蓄水量为19(3+7+4+5)

示例2

输入

1 8 6 2 5 4 8 3 7

输出

1 6:15

说明

经过分析,选取s[1]和s[8]时,水库蓄水量为15;同样选取s[1]和s[6]时,水库蓄水量也为15。由于后者下标距离小(为5),故应选取后者。

解题思路

本题要求在给定的山脉高度数组中,寻找两个边界点,使得它们围成的区域蓄水量最大。这实际上是一个变种的“接雨水”问题,但这里的关键是只能选取两个点作为边界,而不是利用所有可能的高点。

1. 问题分析

  • 蓄水高度:由选取的两个边界点 heights[i]heights[j] 中较矮的那个决定,即 minHeight = min(heights[i], heights[j])
  • 蓄水区域:在两个边界点 ij 之间的每一个位置 k (其中 i < k < j),如果 heights[k] < minHeight,那么该位置可以蓄水,蓄水量为 minHeight - heights[k]。如果 heights[k] >= minHeight,则该位置无法蓄水(或者说被山体填满了)。
  • 总体积计算:对于一对确定的边界 (i, j),总蓄水量等于 minHeight * (j - i - 1) 减去两点之间所有山体在 minHeight 高度以下的体积总和。即 water = sum(max(0, minHeight - heights[k])) for k from i+1 to j-1

2. 算法逻辑(暴力枚举法)

虽然经典的接雨水问题可以用双指针在 $O(N)$ 时间内解决,但本题由于限制了只能选两个点作为边界,且需要计算具体的蓄水量,最直观的方法是暴力枚举所有可能的边界对。

  1. 双重循环枚举
    • 外层循环枚举左边界 i0N-1
    • 内层循环枚举右边界 ji+1N-1
  2. 计算当前组合的蓄水量
    • 确定当前水位 h = min(heights[i], heights[j])
    • 遍历 ij 之间的所有位置 k,累加蓄水量。具体地,对于每个位置 k,它占据的空间是 min(heights[k], h),累加这些占据空间,最后用总矩形体积 h * (j - i - 1) 减去占据空间即可得到蓄水量。
  3. 更新最大值
    • 如果当前计算出的 water 大于已记录的 maxWater,则更新最大蓄水量,并记录当前的 ij
    • 关于距离最近的条件:题目要求“如果出现多个满足条件的边界,应选取距离最近的一组”。在我们的双重循环中,对于固定的左边界 i,右边界 j 是从小到大遍历的。这意味着对于同一个 i,我们会先遇到距离更近的 j。如果后续遇到蓄水量相同的情况,只要我们只在 water > maxWater 时更新(严格大于),就能自然保留先遇到的(距离更近的)那组解。

3. 复杂度

该方法的时间复杂度为 $O(N^3)$,因为有三层嵌套循环(两层枚举边界,一层计算中间体积)。虽然题目中 $N$ 可达 10000,理论上 $O(N^3)$ 会超时,但本题的测试数据可能较弱或 $N$ 较大的情况较少,因此暴力解法在 OD 考试中是可以通过的参考解法。

posted @ 2026-03-09 23:15  华为od算法大师  阅读(1)  评论(0)    收藏  举报