爱吃蟠桃的孙悟空

题目描述

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

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

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

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

输入描述

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

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

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

输出描述

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

示例1

输入

2 3 4 5
4

输出

5

示例2

输入

2 3 4 5
3

输出

解题思路

我们可以通过二分查找的方式来确定孙悟空吃蟠桃的速度 K。首先,我们需要确定二分查找的搜索范围,最小速度 K 的下界是 1,最大速度 K 的上界是所有蟠桃中的最大数量。
对于每一个速度 K,我们可以计算出孙悟空吃完所有蟠桃需要的时间,然后将这个时间与规定的时间 H 进行比较。
如果孙悟空需要的时间小于等于规定的时间,说明速度 K 可行,我们就可以将速度 K 的上界缩小;
如果孙悟空需要的时间大于规定的时间,说明速度 K 不够快,我们就需要将速度 K 的下界增大。

Python

import math

# 判断以速度k是否能在h小时内吃完所有桃子
def can_finish(p, h, k):
    ans = 0
    for x in p:
        ans += math.ceil(x / k)
    return ans <= h

# 读取输入
peach_counts = list(map(int, input().split()))
h = int(input())

# 输入验证
n = len(peach_counts)
if n == 0 or h <= 0 or n >= 10000 or h >= 10000 or n > h:
    print(0)
    exit(0)

# 二分查找最小吃桃速度
left, right = 1, int(1e9)
while left < right:
    mid = (left + right) // 2
    if can_finish(peach_counts, h, mid):
        right = mid
    else:
        left = mid + 1

# 输出最小吃桃速度
print(left)

java

import java.util.*;

public class Main {
    public static void main(String[] args) {
        // 创建一个Scanner对象用于读取输入
        Scanner cin = new Scanner(System.in);
        // 读取一行输入并转换为整数数组,代表每棵桃树上的桃子数量
        int[] peachCounts = Arrays.stream(cin.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
        // 读取下一行输入,转换为整数,代表可用的小时数
        int h = Integer.parseInt(cin.nextLine());
        // 获取桃树的数量
        int n = peachCounts.length;
 
        // 输入验证:如果桃树数量为0,或小时数不合法,或桃树数量大于小时数,则输出0并返回
        if (n == 0 || h <= 0 || n >= 10000 || h >= 10000 || n > h) {
            System.out.println(0);
            return;
        }

        // 初始化二分查找的左右边界
        int left = 1, right = (int)1e9; // 假设最大的吃桃速度不会超过1e9
        // 当左边界小于右边界时,执行二分查找
        while (left < right) {
            // 计算中间值
            int mid = left + (right - left) / 2;
            // 如果以mid的速度可以在h小时内吃完桃子,则尝试更小的速度
            if (canFinish(peachCounts, h, mid)) {
                right = mid;
            } else {
                // 否则尝试更大的速度
                left = mid + 1;
            }
        }

        // 输出最小吃桃速度,此时left是满足条件的最小速度
        System.out.println(left);
    }

    // 定义一个方法,判断以速度k是否能在h小时内吃完所有桃子
    static boolean canFinish(int[] p, int h, int k) {
        // 初始化所需的总小时数
        int ans = 0;
        // 遍历每棵桃树
        for (int x : p) {
            // 计算吃完这棵桃树上桃子所需的小时数,向上取整
            ans += Math.ceil(x * 1.0 / k);
        }
        // 如果所需总小时数小于等于h,则返回true,表示可以完成
        return ans <= h;
    }
}

C++

#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <sstream>
using namespace std;

// 判断以速度k是否能在h小时内吃完所有桃子
bool canFinish(vector<int>& p, int h, int k) {
    long long ans = 0; // 使用 long long 防止溢出
    for (int x : p) {
        ans += ceil(x * 1.0 / k); // 向上取整
    }
    return ans <= h;
}

int main() {
    // 读取输入
    string line;
    getline(cin, line);
    istringstream iss(line);
    vector<int> peachCounts;
    int x;
    while (iss >> x) {
        peachCounts.push_back(x);
    }
    int h;
    cin >> h;

    // 输入验证
    int n = peachCounts.size();
    if (n == 0 || h <= 0 || n >= 10000 || h >= 10000 || n > h) {
        cout << 0 << endl;
        return 0;
    }

    // 二分查找最小吃桃速度
    int left = 1, right = 1e9; // 假设最大的吃桃速度不会超过1e9
    while (left < right) {
        int mid = left + (right - left) / 2;
        if (canFinish(peachCounts, h, mid)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    // 输出最小吃桃速度
    cout << left << endl;
    return 0;
    }
### 孙悟空蟠桃问题的Python实现 针对孙悟空蟠桃的问题,可以通过二分查找算法找到最小速度 \( K \),使得孙悟空能够在给定时间内吃完所有桃子。以下是具体的Python代码实现: ```python def min_eating_speed(piles, h): """ 计算孙悟空能在h小时内吃完所有桃子的最小速度K。 参数: piles (list): 每棵树上的蟠桃数量列表。 h (int): 守卫返回的时间(小时)。 返回: int: 最小速度K;如果无法完成则返回0。 """ # 边界条件处理 if sum(piles) > h * max(piles): return 0 # 初始化二分查找范围 low, high = 1, max(piles) while low < high: mid = (low + high) // 2 hours_needed = sum((pile - 1) // mid + 1 for pile in piles) if hours_needed > h: low = mid + 1 else: high = mid return low if __name__ == "__main__": import sys input_data = list(map(int, " ".join(sys.stdin.readlines()).strip().split())) n = input_data[:-1] h = input_data[-1] result = min_eating_speed(n, h) print(result) ``` 此程序首先定义了一个函数 `min_eating_speed` 来计算所需的最小进食速率。接着,在主程序部分读取标准输入中的数据并调用上述方法得到最终的结果[^1]。 为了使这段代码更易于理解和测试,这里提供了一些额外的功能改进建议以及可能的应用场景扩展方向: - **优化边界判断逻辑**:当前版本假设当总桃数大于最大堆乘以时间时就一定不能完成任务,实际上还可以进一步细化其他特殊情况下的快速退出机制。 - **增加异常捕获功能**:对于非法输入情况应该给予友好提示而不是简单地抛出错误信息。 - **支持更多交互方式**:除了命令行参数外也可以考虑GUI界面让用户更加直观地操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值