2025 B卷 200分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《信道分配》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C++
C
GO
题目名称:信道分配
- 知识点:贪心算法、逻辑处理
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
算法工程师小明需要将通信用的信道分配给尽量多的用户,信道的条件及分配规则如下:
- 所有信道都有属性“阶”,阶为 ( r ) 的信道容量为 ( 2^r ) 比特。
- 所有用户需要传输的数据量相同,均为 ( D ) 比特。
- 一个用户可以分配多个信道,但每个信道只能分配给一个用户。
- 只有当分配给一个用户的所有信道容量之和 ( \geq D ) 时,用户才能传输数据。
输入描述:
- 第一行:一个数字 ( R ),表示最大阶数(( 0 \leq R < 20 ))。
- 第二行:( R+1 ) 个数字,表示每种信道的数量 ( N_i ),按阶从小到大排列(( 0 \leq N_i \leq 1000000 ))。
- 第三行:一个数字 ( D ),表示单个用户所需传输的数据量(( 0 < D < 1000000 ))。
输出描述:
一个数字,表示最多可以满足多少用户传输数据。
示例:
输入:
5
10 5 0 1 3 2
30
输出:
4
说明:通过合理分配信道,最多可满足4个用户的需求。
Java
问题分析
我们需要通过合理分配不同阶的信道,满足尽可能多的用户的数据传输需求。每个用户需要至少D比特的容量,每个阶为r的信道提供的容量为2^r。我们的目标是最大化满足的用户数量。
解题思路
- 贪心策略:优先处理能单独满足用户需求的高阶信道。
- 阶的容量判断:若某阶的单个信道容量≥D,则该阶所有信道都可直接分配给用户。
- 剩余容量处理:对于无法单独满足需求的信道,计算它们的总容量,并尽可能组合分配。
代码实现
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int R = scanner.nextInt(); // 最大阶数
int[] num = new int[R + 1]; // 各阶信道的数量
for (int i = 0; i <= R; i++) {
num[i] = scanner.nextInt();
}
int D = scanner.nextInt(); // 用户需求
int result = 0;
// 处理所有能单独满足用户的高阶信道
for (int r = R; r >= 0; r--) {
long capacity = 1L << r; // 计算2^r
if (capacity >= D) {
result += num[r]; // 该阶所有信道均可单独使用
num[r] = 0; // 标记为已用完
}
}
// 计算剩余信道的总容量
long totalCapacity = 0;
for (int r = 0; r <= R; r++) {
totalCapacity += (long) num[r] * (1L << r);
}
// 剩余容量可满足的用户数
result += totalCapacity / D;
System.out.println(result);
}
}
代码解析
输入读取:
int R = scanner.nextInt();
:读取最大阶数。int[] num = new int[R + 1];
:存储各阶信道数量。int D = scanner.nextInt();
:读取用户需求D。
处理高阶信道:
for (int r = R; r >= 0; r--) { long capacity = 1L << r; // 2^r if (capacity >= D) { result += num[r]; // 累加该阶信道数到结果 num[r] = 0; // 标记为已用 } }
- 从最高阶到最低阶遍历,若当前阶的容量≥D,则所有该阶信道可单独满足用户。
计算剩余总容量:
long totalCapacity = 0; for (int r = 0; r <= R; r++) { totalCapacity += (long) num[r] * (1L << r); }
- 遍历所有阶,累加剩余信道的总容量。
剩余容量分配:
result += totalCapacity / D;
- 剩余总容量可满足的用户数为总容量除以D的商。
示例测试
示例1:
- 输入:
5 10 5 0 1 3 2 30
- 输出:
4
- 解析:高阶信道满足2个用户,剩余容量76满足2个用户,总计4。
- 输入:
示例2:
- 输入:
0 5 3
- 输出:
1
- 解析:所有信道容量总和5,满足1个用户。
- 输入:
示例3:
- 输入:
1 3 1 4
- 输出:
1
- 解析:总容量5满足1个用户。
- 输入:
综合分析
时间复杂度:
- 预处理高阶信道:O®,R为最大阶数(≤20),可忽略。
- 计算剩余总容量:O®。
- 总体时间复杂度:O®,极为高效。
空间复杂度:
- 使用数组存储各阶信道数量,空间复杂度为O®。
正确性保障:
- 高阶信道单独处理确保局部最优。
- 剩余容量总和整除D确保全局最优。
优势:
- 高效性:线性时间处理,适用于大输入规模。
- 简洁性:无需复杂数据结构,逻辑清晰。
适用场景:
- 需要快速分配资源以满足最大用户数的场景,如通信资源分配、云计算资源调度。
python
问题分析
我们需要分配不同阶的信道,使得尽可能多的用户能满足数据传输需求。每个用户需要至少D比特的容量,每个阶r的信道容量为2^r。目标是通过合理分配信道,最大化可以满足的用户数目。
解题思路
贪心策略:
- 处理高阶信道:单个信道容量≥D的高阶信道可直接满足用户,每个信道对应一个用户。
- 组合低阶信道:剩余的信道总容量可组合分配给用户,总容量除以D即为满足的用户数。
步骤:
- 预处理所有能单独满足用户的高阶信道。
- 计算剩余信道的总容量,并用该容量统计可满足的用户数。
代码实现
R = int(input