华为OD机试真题 Java 实现【天然蓄水池】【2023Q1 200分】-LMLPHP

一、题目描述

公元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

五、Java算法源码

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String[] strings = sc.nextLine().split(" ");
    int[] arr = Arrays.stream(strings).mapToInt(Integer::parseInt).toArray();

    // 索引、最大面积
    int l = 0, r = 0, max = 0;
    for (int m = 0, n = arr.length - 1; m < n; m++) {
        // 升序时跳过
        if (arr[m] <= arr[m + 1]) {
            continue;
        }
        // 右指针
        for (int i = m + 2; i <= n; i++) {
            // 降序时跳过
            if (arr[i - 1] >= arr[i]) {
                continue;
            }
            // 高度
            int h = Math.min(arr[m], arr[i]);
            int total = Arrays.stream(arr, m + 1, i)
                    .filter(num -> num < h)
                    .map(num -> h - num)
                    .reduce(0, (a, b) -> a + b);
            // 超出已有最大面积时赋值
            if (total > max) {
                l = m;
                r = i;
                max = total;
            }
        }
    }
    System.out.println(max > 0 ? l + " " + r + ":" + max : "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机试真题 Java 实现【天然蓄水池】【2023Q1 200分】-LMLPHP


🏆本文收录于,华为OD机试(JAVA)(2022&2023)

本专栏包含了最新最全的2023年华为OD机试真题,有详细的分析和Java解答。已帮助1000+同学顺利通过OD机考。专栏会持续更新,每天在线答疑。

华为OD机试真题 Java 实现【天然蓄水池】【2023Q1 200分】-LMLPHP

05-20 16:57