华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
橱窗里有一排宝石,不同的宝石对应不同的价格,宝石的价格标记为 gems[i],0<=i<n, n = gems.length
宝石可同时出售0个或多个,如果同时出售多个,则要求出售的宝石编号连续;
例如客户最大购买宝石个数为m,购买的宝石编号必须为gems[i],gems[i+1]…gemsi+m-1
假设你当前拥有总面值为value的钱,请问最多能购买到多少个宝石,如无法购买宝石,则返回 0。
二、输入描述
第一行输入n,参数类型为int,取值范围:[0,10^6],表示橱窗中宝石的总数量。
之后n行分别表示从第0个到第n-1个宝石的价格,即gems[0]到gems[n-1]的价格,类型为int,取值范围:(0,1000]。
之后一行输入v,类型为int,取值范围:[0,10^9]表示你拥有的钱。
三、输出描述
输出int类型的返回值,表示最大可购买的宝石数量。
四、测试用例
测试用例1
1、输入
7
8
4
6
3
1
6
7
10
2、输出
3
测试用例2
1、输入
9
6
1
3
1
8
9
3
2
4
15
2、输出
4
五、解题思路
- 使用两个指针 left 和 right 来表示滑动窗口的左右边界,初始化它们都为0。
- 不断尝试扩展右边界 right,直到我们无法再购买更多宝石或者超出了我们的预算。
- 在每次尝试扩展右边界的过程中,我们记录当前窗口内的宝石数量,并更新最大宝石数量。
- 如果当前窗口内的宝石总价值超过了我们的预算,我们就需要缩小窗口,即增加左边界 left,直到窗口内的宝石总价值不再超过预算或左边界 left 达到了 n - m,这是因为在这种情况下即使窗口再向右扩展也无法满足连续购买的条件。
- 最后,返回记录的最大宝石数量即可。
六、Python算法源码
# 导入必要的模块
import sysdef main():import sysimport sys# 读取输入input = sys.stdin.read().split()idx = 0n = int(input[idx]) # 宝石的总数量idx +=1gems = []for _ in range(n):gems.append(int(input[idx])) # 读取每个宝石的价格idx +=1if idx < len(input):v = int(input[idx]) # 读取拥有的钱else:v =0 # 如果没有输入v,默认v为0left = 0 # 滑动窗口左边界right =0 # 滑动窗口右边界maxGems =0 # 最大可购买宝石数量sum_val =0 # 当前窗口内宝石总价值# 开始滑动窗口while right <n:sum_val += gems[right] # 尝试扩展右边界,并更新窗口内宝石总价值right +=1# 如果当前窗口内宝石总价值超过了预算,缩小窗口while sum_val >v and left <n:sum_val -= gems[left] # 缩小窗口,更新宝石总价值left +=1# 更新最大可购买宝石数量maxGems = max(maxGems, right - left)print(maxGems) # 输出结果if __name__ == "__main__":main()
七、JavaScript算法源码
// 导入读取模块
const readline = require('readline');// 创建接口
const rl = readline.createInterface({input: process.stdin,output: process.stdout
});let input = [];
rl.on('line', (line) => {input.push(line);
}).on('close', () => {let idx = 0;const n = parseInt(input[idx++]); // 宝石的总数量let gems = [];for(let i=0;i<n;i++){gems.push(parseInt(input[idx++])) // 读取每个宝石的价格}const v = parseInt(input[idx++]) || 0; // 读取拥有的钱,若无输入则为0let left =0; // 滑动窗口左边界let right =0; // 滑动窗口右边界let maxGems =0; // 最大可购买宝石数量let sum =0; // 当前窗口内宝石总价值// 开始滑动窗口while(right <n){sum += gems[right]; // 尝试扩展右边界,并更新窗口内宝石总价值right++;// 如果当前窗口内宝石总价值超过了预算,缩小窗口while(sum >v && left <n){sum -= gems[left]; // 缩小窗口,更新宝石总价值left++;}// 更新最大可购买宝石数量maxGems = Math.max(maxGems, right - left);}console.log(maxGems); // 输出结果
});
八、C算法源码
#include <stdio.h>// 主函数
int main(){int n;scanf("%d", &n); // 宝石的总数量int gems[n];for(int i=0;i<n;i++){scanf("%d", &gems[i]); // 读取每个宝石的价格}long long v;scanf("%lld", &v); // 读取拥有的钱int left =0; // 滑动窗口左边界int right =0; // 滑动窗口右边界int maxGems =0; // 最大可购买宝石数量long long sum =0; // 当前窗口内宝石总价值// 开始滑动窗口while(right <n){sum += gems[right]; // 尝试扩展右边界,并更新窗口内宝石总价值right++;// 如果当前窗口内宝石总价值超过了预算,缩小窗口while(sum > v && left <n){sum -= gems[left]; // 缩小窗口,更新宝石总价值left++;}// 更新最大可购买宝石数量if(right - left > maxGems){maxGems = right - left;}}printf("%d\n", maxGems); // 输出结果return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;int main(){ios::sync_with_stdio(false);cin.tie(0);int n;cin >> n; // 宝石的总数量vector<int> gems(n);for(int &x : gems){cin >> x; // 读取每个宝石的价格}long long v;cin >> v; // 读取拥有的钱int left =0; // 滑动窗口左边界int right =0; // 滑动窗口右边界int maxGems =0; // 最大可购买宝石数量long long sum =0; // 当前窗口内宝石总价值// 开始滑动窗口while(right <n){sum += gems[right]; // 尝试扩展右边界,并更新窗口内宝石总价值right++;// 如果当前窗口内宝石总价值超过了预算,缩小窗口while(sum >v && left <n){sum -= gems[left]; // 缩小窗口,更新宝石总价值left++;}// 更新最大可购买宝石数量maxGems = max(maxGems, right - left);}cout << maxGems << "\n"; // 输出结果return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。