孙悟空吃蟠桃 - 华为OD统一考试

OD统一考试(C卷)

分值: 200分

题解: Java / Python / C++

孙悟空吃蟠桃 - 华为OD统一考试_第1张图片

题目描述

孙悟空爱吃蟠桃,有一天趁着蟠桃园守卫不在来偷吃。已知蟠桃园有 N 棵蟠桃树,每棵树上都桃子,守卫将在 H 小时后回来。

孙悟空可以决定他吃蟠桃的速度 K (个/每小时),每个小时选一棵桃树,并从树上吃掉 K 个,如果K大于该树上所有桃子个数,则全部吃掉,并且这一小时剩余的时间里不再吃桃。

孙悟空喜欢慢慢吃,但又想在守卫回来前吃完桃子。

请返回孙悟空可以在 H 小时内吃掉所有桃子的最小速度 KK 为整数)。如果以任何速度都吃不完所有桃子,则返回 0。

输入描述

第一行输入为 N个数字, N 表示桃树的数量,这 N 个数字表示每棵桃树上蟠桃的数量。

第二行输入为一个数字,表示守卫离开的时间 H

其中数字通过空格分割, NH 为正整数,每棵树上都有蟠桃,且 0<N<10000, 0 < H < 10000。

输出描述

输出吃掉所有蟠桃的最小速度 K,无解或输入异常时输出 0。

示例1

输入:
2 3 4 5
4

输出:
5

示例2

输入:
2 3 4 5
3

输出:
0

示例3

输入:
30 11 23 4 20
6

输出:
23

题解

结合以上的题目和以下题目代码解法总结一些题解信息。

从以下几点方面: 题目属于什么类型的算法题(例如,动态规划、DFS、BFS、贪心、双指针 …),解题思路,代码大致描述,时间复杂度,空间复杂度,及同类型 leetcode.cn 的题目

Java

import java.util.Arrays;
import java.util.Scanner;

/**
 * @author code5bug
 */
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 每棵桃树上蟠桃的数量
        int[] peachs = Arrays.stream(scanner.nextLine().split(" "))
                .mapToInt(Integer::parseInt).toArray();

        // 守卫离开的时间
        int H = scanner.nextInt();

        System.out.println(solve(peachs, H));
    }

    /**
     * 每个小时只能选一棵桃树,能否在 H 小时内吃完所有的桃子
     *
     * @param peachs 每棵桃树上蟠桃的数量
     * @param speed  守卫每小时吃的桃子数量
     * @param H      守卫离开的时间
     * @return 每个小时只能选一棵桃树,能否在 H 小时内吃完所有的桃子
     */
    private static boolean ok(int[] peachs, int speed, int H) {
        int time = 0;
        for (int cnt : peachs) {
            time += (cnt + speed - 1) / speed;  // 向上取整
        }
        return time <= H;
    }

    /**
     * 计算守卫在 H 小时内能吃完所有的桃子的最小速度
     *
     * @param peachs 每棵桃树上蟠桃的数量
     * @param H      守卫离开的时间
     * @return 守卫在 H 小时内能吃完所有的桃子的最小速度
     */
    private static int solve(int[] peachs, int H) {
        int n = peachs.length;

        // 每个小时只能选一棵桃树,因此任何速度都吃不完所有桃子
        if (n > H) {
            return 0;
        }

        int l = 0, r = Arrays.stream(peachs).max().orElse(0);
        while (l + 1 < r) {
            int mid = (l + r) / 2;
            if (ok(peachs, mid, H)) {
                r = mid;
            } else {
                l = mid;
            }
        }
        return r;
    }
}

Python

from typing import List


def ok(peachs: List[int], speed: int, H: int) -> bool:
    """
    :param peachs: 每棵桃树上蟠桃的数量
    :param speed: 守卫每小时吃的桃子数量
    :param H: 守卫离开的时间
    :return:  每个小时只能选一棵桃树,能否在 H 小时内吃完所有的桃子
    """
    time = 0
    for cnt in peachs:
        time += (cnt + speed - 1) // speed  # 向上取整

    return time <= H


def solve(peachs: List[int], H: int) -> int:
    n = len(peachs)

    # 每个小时只能选一棵桃树,因此任何速度都吃不完所有桃子
    if n > H:
        return 0

    l, r = 0, max(peachs)
    while l + 1 < r:
        mid = (l + r) // 2
        if ok(peachs, mid, H):
            r = mid
        else:
            l = mid
    return r


if __name__ == '__main__':
    # 每棵桃树上蟠桃的数量
    peachs = list(map(int, input().split()))

    # 守卫离开的时间
    H = int(input())

    print(solve(peachs, H))

C++

#include 
#include 
#include 

using namespace std;

/**
 * 每个小时只能选一棵桃树,能否在 H 小时内吃完所有的桃子
 *
 * @param peachs 每棵桃树上蟠桃的数量
 * @param speed  守卫每小时吃的桃子数量
 * @param H      守卫离开的时间
 * @return 每个小时只能选一棵桃树,能否在 H 小时内吃完所有的桃子
 */
bool ok(const vector<int>& peachs, int speed, int H) {
    int time = 0;
    for (int cnt : peachs) {
        time += (cnt + speed - 1) / speed;  // 向上取整

        if(time > H) return false;
    }
    return true;
}

/**
 * 计算守卫在 H 小时内能吃完所有的桃子的最小速度
 *
 * @param peachs 每棵桃树上蟠桃的数量
 * @param H      守卫离开的时间
 * @return 守卫在 H 小时内能吃完所有的桃子的最小速度
 */
int solve(const vector<int>& peachs, const int H) {
    int n = peachs.size();

    // 每个小时只能选一棵桃树,因此任何速度都吃不完所有桃子
    if (n > H) {
        return 0;
    }

    int l = 0, r = *max_element(peachs.begin(), peachs.end());
    while (l + 1 < r) {
        int mid = (l + r) / 2;
        if (ok(peachs, mid, H)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    return r;
}

int main() {
    // 每棵桃树上蟠桃的数量
    vector<int> peachs;
    int peach;
    while (cin >> peach) {
        peachs.push_back(peach);
    }

    // 守卫离开的时间
    int H = peachs.back();
    peachs.pop_back();

    cout << solve(peachs, H) << endl;

    return 0;
}

相关练习题

题号 题目 难易
LeetCode 1631 1631. 最小体力消耗路径 中等
LeetCode 2226 2226. 每个小孩最多能分到多少糖果 中等

‍❤️‍华为OD机试面试交流群每日真题分享): 加V时备注“华为od加群”

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。

你可能感兴趣的:(华为od,算法,java,python,c++,面试,机试)