OD统一考试(C卷)
分值: 200分
题解: Java / Python / C++
孙悟空爱吃蟠桃,有一天趁着蟠桃园守卫不在来偷吃。已知蟠桃园有 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
输入:
30 11 23 4 20
6
输出:
23
结合以上的题目和以下题目代码解法总结一些题解信息。
从以下几点方面: 题目属于什么类型的算法题(例如,动态规划、DFS、BFS、贪心、双指针 …),解题思路,代码大致描述,时间复杂度,空间复杂度,及同类型 leetcode.cn 的题目
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;
}
}
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))
#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加群”
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。