一、题目描述
公元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
四、补充说明
数组s满足:
1 <= length(s) <= 10000
0 <= s[i] <= 10000
五、解题思路
- 读取输入的山脉数组s。
- 初始化左边界l、右边界r和最大蓄水量max为0。
- 使用两个指针m和n分别指向山脉数组的第一个和最后一个元素。
- 遍历山脉数组,从m=0到n-1:
- 如果当前山脉高度小于等于下一个山脉高度(升序),则跳过当前山脉,继续下一轮循环。
- 否则,使用一个新的指针i从m+2到n,遍历右边界:
- 如果当前山脉高度大于等于前一个山脉高度(降序),则跳过当前山脉,继续下一轮循环。
- 否则,计算当前左边界和右边界之间的蓄水量:
- 获取左边界和右边界之间的高度h,即左边界和右边界中较小的山脉高度。
- 使用流处理左边界和右边界之间的山脉高度,过滤出高度小于h的山脉,计算蓄水量(h - num)并求和。
- 如果蓄水量大于已有的最大蓄水量max,则更新左边界l、右边界r和最大蓄水量max。
- 输出最大蓄水量和边界信息:
- 如果最大蓄水量大于0,则输出左边界l、右边界r和最大蓄水量max。
- 否则,输出0表示无法蓄水。
六、Python算法源码
def calculate_max_reservoir(arr):
l = 0
r = 0
max_reservoir = 0
n = len(arr)
for m in range(n - 1):
if arr[m] <= arr[m + 1]:
continue
for i in range(m + 2, n):
if arr[i - 1] >= arr[i]:
continue
h = min(arr[m], arr[i])
total = sum(h - num for num in arr[m + 1:i] if num < h)
if total > max_reservoir:
l = m
r = i
max_reservoir = total
return f"{l} {r}:{max_reservoir}" if max_reservoir > 0 else "0"
七、效果展示
1、输入
1 9 6 2 5 4 9 3 7
2、输出
1 6:19
3、说明
经过分析,选取s[1]和s[6]时,水库蓄水量为19(3 + 7 + 4 + 5)。
🏆下一篇:华为OD机试真题 Python 实现【相对开音节】【2022Q4 100分】,附详细解题思路
🏆本文收录于,华为OD机试(Python)真题(A卷+B卷)
每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。