华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
孙悟空喜欢吃蟠桃,一天他乘守卫蟠桃园的天兵天将离开了而偷偷的来到王母娘娘的蟠桃园偷吃蟠桃。
已知蟠桃园有 N 棵蟠桃树,第 i 棵蟠桃树上有 N[i](大于 0)个蟠桃,天兵天将将在 H(不小于蟠桃树棵数)小时后回来。
孙悟空可以决定他吃蟠桃的速度 K(单位:个/小时),每个小时他会选择一颗蟠桃树,从中吃掉 K 个蟠桃,如果这棵树上的蟠桃数小于 K,他将吃掉这棵树上所有蟠桃,然后这一小时内不再吃其余蟠桃树上的蟠桃。
孙悟空喜欢慢慢吃,但仍想在天兵天将回来前将所有蟠桃吃完。
求孙悟空可以在 H 小时内吃掉所有蟠桃的最小速度 K(K 为整数)。
二、输入描述
从标准输入中读取一行数字,前面数字表示每棵数上蟠桃个数,最后的数字表示天兵天将将离开的时间。
三、输出描述
吃掉所有蟠桃的 最小速度 K(K 为整数)或 输入异常时输出 -1。
四、测试用例
测试用例1
1、输入
3 11 6 7 8
2、输出
4
3、说明
天兵天将8个小时后回来,孙悟空吃掉所有蟠桃的最小速度4。
- 第1小时全部吃完第一棵树,吃3个,
- 第2小时吃4个,第二棵树剩7个,
- 第3小时吃4个,第二棵树剩3个,
- 第4小时吃3个,第二棵树吃完,
- 第5小时吃4个,第三棵树剩2个,
- 第6小时吃2个,第三棵树吃完,
- 第7小时吃4个,第4棵树剩3个,
- 第8小时吃3个,第4棵树吃完。
测试用例2
1、输入
1 2 3 4 10
2、输出
1
3、说明
H=10,K=1,可以每小时吃1个蟠桃,10小时吃完所有。
五、解题思路
1、问题分析
题目描述有点复杂,多读几遍不难理解,意思就是:
一个小时只能在一棵桃树上吃,如果吃不完,下一个小时继续吃,如果吃完了,就不吃了,但不能去吃下一颗桃树,要守规矩。
- 输入几个数,表示每颗树的桃子数量;
- 在H个小时内,以最慢的速度将这些桃子全部吃完。
很明显的回溯问题,一个一个找呗,看哪个速度最合适。
2、具体解题思路
- 输入验证:
- 确保输入不为空,且包含至少一个蟠桃树和一个时间H。
- 确保所有蟠桃数量和H都是正整数。
- 确保H大于等于蟠桃树的数量,因为每小时只能吃一棵树。
- 算法选择:
- 二分查找: 采用二分查找在可能的K值范围内寻找最小的可行速度。
- 左边界为1(最慢速度)。
- 右边界为最大蟠桃数(最快速度)。
- 判断函数 (canEatAll):
- 对于每棵树,计算吃完该树所需的时间(小时数)。
- 累加所有树的吃完时间,若总时间小于等于H,则当前速度K可行。
- 优化点:在累加过程中,如果时间已超过H,立即返回false,减少不必要的计算。
- 减少排序操作: 通过遍历找到最大蟠桃数,避免排序带来的额外时间开销。
- 提前终止: 在判断函数中,当累加时间超过H时,立即返回false。
六、Python算法源码
# 导入所需模块
import math
import sysdef main():try:# 读取输入并分割成整数列表input_line = sys.stdin.readline().strip()if not input_line:print(-1)returntokens = input_line.split()if len(tokens) < 2:print(-1)return# 获取蟠桃树数量和Hpeaches = []for token in tokens[:-1]:num = int(token)if num <= 0:print(-1)returnpeaches.append(num)H = int(tokens[-1])num_trees = len(peaches)if H < num_trees:print(-1)returnmax_peaches = max(peaches)left, right = 1, max_peacheswhile left < right:mid = left + (right - left) // 2if can_eat_all(peaches, H, mid):right = midelse:left = mid + 1print(left)except:print(-1)def can_eat_all(peaches, H, K):times = 0for p in peaches:times += p // Kif p % K != 0:times += 1if times > H:return Falsereturn Trueif __name__ == "__main__":main()
七、JavaScript算法源码
// 读取标准输入
const readline = require('readline');const rl = readline.createInterface({input: process.stdin,output: process.stdout
});function canEatAll(peaches, H, K) {let times = 0;for (let p of peaches) {times += Math.floor(p / K);if (p % K !== 0) {times += 1;}if (times > H) {return false;}}return true;
}rl.on('line', (input) => {try {input = input.trim();if (input === "") {console.log(-1);rl.close();return;}const tokens = input.split(/\s+/);if (tokens.length < 2) {console.log(-1);rl.close();return;}const peaches = [];for (let i = 0; i < tokens.length - 1; i++) {let num = parseInt(tokens[i]);if (isNaN(num) || num <= 0) {console.log(-1);rl.close();return;}peaches.push(num);}const H = parseInt(tokens[tokens.length - 1]);const numTrees = peaches.length;if (isNaN(H) || H < numTrees) {console.log(-1);rl.close();return;}const maxPeaches = Math.max(...peaches);let left = 1;let right = maxPeaches;while (left < right) {let mid = Math.floor((left + right) / 2);if (canEatAll(peaches, H, mid)) {right = mid;} else {left = mid + 1;}}console.log(left);} catch (e) {console.log(-1);}rl.close();
});
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>// 判断是否可以在H小时内吃完所有蟠桃,速度K
int canEatAll(int *peaches, int numTrees, int H, int K) {int times = 0;for(int i = 0; i < numTrees; i++) {times += peaches[i] / K;if(peaches[i] % K != 0) {times += 1;}if(times > H) {return 0; // false}}return 1; // true
}int main(){char inputLine[1000];if(!fgets(inputLine, sizeof(inputLine), stdin)) {printf("-1\n");return 0;}// 去除末尾换行符inputLine[strcspn(inputLine, "\n")] = 0;// 分割输入char *token = strtok(inputLine, " ");int nums[1000];int count = 0;while(token != NULL){nums[count++] = atoi(token);token = strtok(NULL, " ");}if(count < 2){printf("-1\n");return 0;}int H = nums[count -1];int numTrees = count -1;// 检查所有数是否大于0for(int i =0; i < count; i++) {if(nums[i] <=0 ){printf("-1\n");return 0;}}if(H < numTrees){printf("-1\n");return 0;}// 获取蟠桃数并找到最大值int peaches[numTrees];int maxPeaches = 0;for(int i =0; i < numTrees; i++) {peaches[i] = nums[i];if(peaches[i] > maxPeaches){maxPeaches = peaches[i];}}// 二分查找int left =1, right = maxPeaches, result = maxPeaches;while(left < right){int mid = left + (right - left) /2;if(canEatAll(peaches, numTrees, H, mid)){right = mid;}else{left = mid +1;}}printf("%d\n", left);return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;// 判断是否可以在H小时内吃完所有蟠桃,速度K
bool canEatAll(vector<int> &peaches, int H, int K){int times = 0;for(auto p : peaches){times += p / K;if(p % K != 0){times +=1;}if(times > H){return false;}}return true;
}int main(){string inputLine;if(!getline(cin, inputLine)){cout << "-1" << endl;return 0;}// 分割输入vector<int> nums;int num;stringstream ss(inputLine);while(ss >> num){nums.push_back(num);}if(nums.size() <2){cout << "-1" << endl;return 0;}int H = nums.back();nums.pop_back();int numTrees = nums.size();// 检查所有数是否大于0for(auto p : nums){if(p <=0){cout << "-1" << endl;return 0;}}if(H < numTrees){cout << "-1" << endl;return 0;}// 找到最大值int maxPeaches = *max_element(nums.begin(), nums.end());// 二分查找int left =1, right = maxPeaches;while(left < right){int mid = left + (right - left)/2;if(canEatAll(nums, H, mid)){right = mid;}else{left = mid +1;}}cout << left << endl;return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。