【OD机试题解法笔记】爱吃蟠桃的孙悟空

题目

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

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

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

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

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

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

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

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

用例

输入输出

2  3  4  5

4

5

2  3  4  5

3

0

思考

题目大意是要求孙悟空在H小时内以最小速度吃完N棵树上的桃子。

细节:1、一小时只能吃一棵树的桃子,如果提前吃完了,也得等到下一个小时继续吃别的桃子树;2、如果桃子树数量大于守卫离开时长,则不可能吃完所有桃子树,直接返回0。

考虑在桃树数量小于等于守卫离开时长H情形下的最小吃桃速度。吃桃速度取决于桃树的桃子数量。若吃桃速度为数量最大的桃树数量,则一定能吃完所有桃子,而吃桃的最小速度是1个/棵树,如果一颗树一小时吃不完,会导致总的吃桃时长超过桃树数量,而这种情形比较适合桃树数量少于守卫离开时长数。因此目标是在区间[1, max](max是桃树桃子数目最大值)中查找一个最小值且能满足在H时长内吃完所有桃树桃子,可以使用二分查找解决。

算法过程

1、判断桃树数量是否大于守卫离开时长数H,若是直接返回0,无解,否则进入第二步;

2、找到桃子数量最大值Max,在区间[1, Max]进行二分查找,目标找到最小的速度数值满足能在规定时间H内吃完所有桃树;

3、定义一个 check 函数接受一个速度参数,返回结果是能不能按给定的速度在给定时长数H内吃完所有桃子,定义一个最小速度变量初始化为Max,用于记录最终结果;

4、二分查找序列,不断把速度值向序列左侧边界推进,同时将每轮查找到满足规定时间吃完所有桃树桃子的速度与最小速度变量进行比较更新最小速度。当查找的速度值不满足条件了,记录的最小速度便是最终结果。

参考代码

function solution() {
    const nums = readline().split(' ').map(Number);
    const H = Number(readline());
    const N = nums.length;
    
    // 若桃树数量 > H,必然吃不完(每棵至少1小时)
    if (N > H) {
        console.log(0);
        return;
    }
    
    // 检查速度为speed时,是否能在H小时内吃完
    const check = (speed) => {
        let hours = 0;
        for (const num of nums) {
            hours += Math.ceil(num / speed);
            if (hours > H) return false; // 提前退出,优化性能
        }
        return hours <= H;
    };

    // 二分查找:low从1开始,high为最大桃子数
    let low = 1;
    let high = Math.max(...nums);
    let ans = 0;
    
    while (low <= high) {
        const mid = Math.floor((low + high) / 2);
        if (check(mid)) {
            ans = mid; // 记录当前合法速度
            high = mid - 1; // 尝试更小的速度
        } else {
            low = mid + 1; // 速度不够,需要更大的速度
        }
    }

    console.log(ans);
}

// 测试用例
const cases = [
    `2 3 4 5
4`,
    `2 3 4 5
3`,
    `4 4
5`, // 应输出2
    `3 3
4`  // 应输出2(3/2=2小时每棵,总时间4)
];

let caseIndex = 0, lineIndex = 0;
const readline = (() => {
    let lines = [];
    return () => {
        if (!lineIndex) lines = cases[caseIndex].trim().split('\n').map(l => l.trim());
        return lines[lineIndex++];
    };
})();

cases.forEach((_, i) => {
    caseIndex = i;
    lineIndex = 0;
    solution();
    console.log('-------');
});

孙悟空蟠桃时,华为OD可能会通过其技术和产品提供支持与帮助。 首先,华为OD是华为的开放开发平台,为开发者和合作伙伴提供了丰富的技术资源和开发工具。在孙悟空蟠桃的场景下,华为OD可能会提供一种基于物联网技术的智能食品追溯系统。这个系统可以追踪蟠桃的种植、采摘、存储、运输等环节的信息,确保蟠桃的安全和品质。开发者可以通过华为OD平台的技术资源和工具,以及与华为合作伙伴的协作,构建这样一个智能食品追溯系统。 其次,华为OD平台可能还提供一些与孙悟空蟠桃相关的应用程序。比如,一个基于华为OD平台的智能家居应用,可以通过识别孙悟空的声音或人脸,自动提供一些便利的功能。比如,当孙悟空靠近蟠桃时,系统可以自动将蟠桃洗净或剥皮,或者提供一些有关蟠桃的健康食谱推荐。 最后,华为OD平台还可能提供一些与蟠桃相关的社交媒体应用。可以想象,孙悟空蟠桃的场景会引起很多人的兴趣和关注,人们可能愿意分享自己的蟠桃经历、菜谱或者与孙悟空的互动等。华为OD平台可以提供一个社交媒体平台,让用户可以方便地分享和交流这些有趣的内容。 总之,华为OD可能会通过技术支持、应用开发和社交媒体等方面,为孙悟空蟠桃这个场景提供多样化的解决方案和体验。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值