华为OD机试 2023B卷题库疯狂收录中,刷题点这里
本专栏收录于《华为OD机试(JAVA)真题(A卷+B卷)》。
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。
小牛的孩子生日快要到了,他打算给孩子买蛋糕和小礼物,蛋糕和小礼物各买一个,他的预算不超过x元。蛋糕cake和小礼物gift都有多种价位的可供选择。
请返回小牛共有多少种购买方案。
输出数字表示购买方案的总数。
备注:
1 < cake.length <= 105;
1 < gift.length <= 105;
1 < cake[i],gift[i] <= 105;
1 < X <= 2 * 105;
这道题题意很简单,就是第一行选一个数、第二行选一个数,两数之和小于第三行的数,统计一下有多少种组合。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// 蛋糕cakes
int[] cakes = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();
// 小礼物gifts
int[] gifts = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();
// 预算
int X = Integer.parseInt(sc.nextLine());
// 对礼物gifts进行升序排序
Arrays.sort(gifts);
// 一共多少种购买方式
int buyMethodSum = 0;
// 遍历蛋糕集合cakes
for (int cake : cakes) {
if (X <= cake) {
continue;
}
// 找到最大的满足位置
int max = searchLast(gifts, X - cake);
if (max >= 0) {
// 返回的最大满足位置 + 1(因为下角标从0开始) = 在购买当前蛋糕时,可以买多少种小礼物
buyMethodSum += max + 1;
} else {
max = -max - 1;
buyMethodSum += max;
}
}
System.out.println(buyMethodSum);
}
/**
* 遍历礼物集合gifts,二分查找, 找到最大的满足位置
*
* @param gifts 礼物集合
* @param target 预算 - 蛋糕
* @return 最大的满足位置
*/
public static int searchLast(int[] gifts, int target) {
int left = 0;
int right = gifts.length - 1;
while (left <= right) {
// 二分查找
int mid = (left + right) >> 1;
// 如果中间数 大于 剩余预算
if (gifts[mid] > target) {
right = mid - 1;
} else if (gifts[mid] < target) {// 如果中间数 小于 剩余预算
left = mid + 1;
} else {// 如果中间数 等于 剩余预算
/**
* 如果中间位置最后一个(遍历光了)
* 或者
* 中间位置的数 不等于 中间位置的下一个数(因为要求找到最大的满足位置,挨着的数不相等,相等的话要取下一个位置)
* 直接返回mid位置
*/
if (mid == gifts.length - 1 || gifts[mid] != gifts[mid + 1]) {
return mid;
} else {//否则继续向右二分查找
left = mid + 1;
}
}
}
return -left - 1;
}
10,15,20
5,7,9
25
7
这道题题意很简单,就是第一行选一个数、第二行选一个数,两数之和小于第三行的数,统计一下有多少种组合。
下一篇:华为OD机试真题 Java 实现【路灯照明问题】【2022Q4 100分】,感谢fly晨发现这个问题,并提供更优质的算法
本文收录于,华为OD机试(JAVA)真题(A卷+B卷)
刷的越多,抽中的概率越大,每一题都有详细的答题思路、详细的代码注释、样例测试,订阅后,专栏内的文章都可看,可加入华为OD刷题群(私信即可),发现新题目,随时更新,全天CSDN在线答疑。