2025 A卷 100分 题型
本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!
本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享》
华为OD机试真题《数据分类》:
目录
题目名称:数据分类
- 知识点:位运算、逻辑处理
- 时间限制:1秒
- 空间限制:256MB
- 限定语言:不限
题目描述
对一个数据 a 进行分类,分类方法为:
- 将 a(四个字节大小)的四个字节的十进制值相加,得到一个总和。
- 将此总和对一个给定的值 b 取模。
- 若取模结果小于另一个给定值 c,则该结果为 a 的有效类型;否则类型无效。
输入描述
- 输入12个数据,以空格分隔:
- 第一个数据为 c,第二个数据为 b,剩余10个数据为待分类的整数(每个数 ≤ 1e9)。
输出描述
- 统计有效类型中包含数据最多的类型,输出其数据个数。若所有类型均无效,输出
0
。
示例1
输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
说明
- 每个数转换为四个字节的十六进制字符串(不足8位补前导0),例如256补为
00000100
,每个字节转为十进制相加,结果为0 + 0 + 1 + 0 = 1
。 - 10个数的总和分别为
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
,对4取模结果为1, 2, 3, 0, 1, 2, 3, 0, 1, 2
。 - 因
c=3
,有效类型为0、1、2,其中类型1和2各有3个数据,故输出3。
补充说明
- 每个整数需转换为四个字节的十六进制表示,例如
256
转为00000100
,拆分后字节为0x00, 0x00, 0x01, 0x00
。 - 需统计所有有效类型的出现次数,取最大值。
Java
问题分析
我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。
解题思路
- 输入处理:读取c、b和10个待分类的整数。
- 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
- 模运算与分类:计算字节和对b取模,判断是否小于c,记录有效类型。
- 统计与输出:统计有效类型的出现次数,输出最大值。
代码实现
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String[] input = scanner.nextLine().split(" ");
// 解析输入参数
int c = Integer.parseInt(input[0]);
int b = Integer.parseInt(input[1]);
int[] nums = new int[10];
for (int i = 0; i < 10; i++) {
nums[i] = Integer.parseInt(input[i + 2]);
}
Map<Integer, Integer> typeCount = new HashMap<>(); // 统计有效类型出现次数
for (int num : nums) {
// 计算四个字节的十进制和
int sum = 0;
sum += (num >> 24) & 0xFF; // 最高位字节
sum += (num >> 16) & 0xFF;
sum += (num >> 8) & 0xFF;
sum += num & 0xFF; // 最低位字节
int mod = sum % b; // 取模结果
if (mod < c) { // 判断是否有效
typeCount.put(mod, typeCount.getOrDefault(mod, 0) + 1);
}
}
// 找出最大出现次数
int max = 0;
for (int count : typeCount.values()) {
if (count > max) max = count;
}
System.out.println(max);
}
}
代码详细解析
- 输入处理:使用
Scanner
读取输入并分割成字符串数组,解析出c
、b
和10个整数。 - 字节和计算:
- 通过位运算
(num >> n) & 0xFF
依次提取四个字节的值。 - 累加四个字节的十进制值得到总和。
- 通过位运算
- 模运算与分类:计算总和对
b
取模,若结果小于c
则记录到哈希表中。 - 统计与输出:遍历哈希表的值,找到最大出现次数并输出。
示例测试
示例1输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
解析:有效类型为0、1、2,类型1和2各出现3次。
示例2输入:
5 3 1 2 3 4 5 6 7 8 9 10
输出:
10
解析:所有模结果均小于5,所有类型有效,最大值10。
示例3输入:
0 1 100 200 300 400 500 600 700 800 900 1000
输出:
0
解析:c=0
,所有模结果不小于0,无有效类型。
综合分析
- 时间复杂度:O(n),其中n=10,每个数处理时间为常数。
- 空间复杂度:O(k),k为有效类型数量,最多为min(b, c)。
- 优势:
- 高效位运算:快速提取字节值,无需复杂转换。
- 哈希表统计:O(1)时间记录和查询频率。
- 适用场景:适用于大范围整数分类,满足时间与空间要求。
python
问题分析
我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。
解题思路
- 输入处理:读取c、b和10个待分类的整数。
- 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
- 模运算与分类:计算字节和对b取模,判断是否小于c,记录有效类型。
- 统计与输出:统计有效类型的出现次数,输出最大值。
代码实现
# 读取输入并解析
input_list = list(map(int, input().split()))
c = input_list[0]
b = input_list[1]
nums = input_list[2:12]
# 统计有效类型出现次数
type_count = {}
for num in nums:
# 提取四个字节的十进制值
byte1 = (num >> 24) & 0xFF # 最高位字节
byte2 = (num >> 16) & 0xFF
byte3 = (num >> 8) & 0xFF
byte4 = num & 0xFF # 最低位字节
total = byte1 + byte2 + byte3 + byte4
# 计算模结果并判断有效性
mod = total % b
if mod < c:
type_count[mod] = type_count.get(mod, 0) + 1
# 找出最大出现次数
max_count = max(type_count.values()) if type_count else 0
print(max_count)
代码详细解析
输入处理:
input().split()
读取输入并分割成字符串列表map(int, ...)
转换为整数列表- 第一个元素为
c
,第二个为b
,后续为待处理的10个整数
字节提取:
(num >> 24) & 0xFF
:右移24位获取最高位字节(num >> 16) & 0xFF
:右移16位获取第二个字节(num >> 8) & 0xFF
:右移8位获取第三个字节num & 0xFF
:直接取最低位字节
求和与分类:
- 计算四个字节之和
total
total % b
计算模结果- 若模结果
< c
则记录到字典type_count
- 计算四个字节之和
统计结果:
- 若字典非空则取最大值,否则输出0
示例测试
示例1输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
解析:
- 256的字节和为1 → 1%4=1(有效)
- 类型1和2各出现3次,最大值3
示例2输入:
5 3 1 2 3 4 5 6 7 8 9 10
输出:
10
解析:
- 所有数的模结果均小于5,最大值10
示例3输入:
0 1 100 200 300 400 500 600 700 800 900 1000
输出:
0
解析:
- 所有模结果≥0,但c=0,均无效
综合分析
- 时间复杂度:O(n),其中n=10,每个数处理时间为O(1)
- 空间复杂度:O(k),k为有效类型数量(最多为b)
- 优势:
- 位运算高效:直接通过位移和掩码提取字节,无需类型转换
- 哈希表快速统计:字典操作时间复杂度为O(1)
- 适用场景:适用于大规模整数处理,满足时间与空间要求
JavaScript
问题分析
我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。
解题思路
- 输入处理:读取
c
、b
和10个待分类的整数。 - 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
- 模运算与分类:计算字节和对
b
取模,判断是否小于c
,记录有效类型。 - 统计与输出:统计有效类型的出现次数,输出最大值。
代码实现
const fs = require('fs');
const input = fs.readFileSync(0).toString().trim().split(/\s+/);
// 解析输入参数
const c = parseInt(input[0], 10);
const b = parseInt(input[1], 10);
const nums = input.slice(2, 12).map(num => parseInt(num, 10));
const typeCount = {}; // 记录有效类型出现次数
/**
* 计算整数的四个字节之和
* @param {number} num - 待处理的整数
* @returns {number} 四个字节的十进制和
*/
function getByteSum(num) {
const byte1 = (num >> 24) & 0xff; // 最高位字节
const byte2 = (num >> 16) & 0xff;
const byte3 = (num >> 8) & 0xff;
const byte4 = num & 0xff; // 最低位字节
return byte1 + byte2 + byte3 + byte4;
}
// 处理每个数字
for (const num of nums) {
const sum = getByteSum(num);
const mod = sum % b; // 计算模结果
if (mod < c) { // 判断有效性
typeCount[mod] = (typeCount[mod] || 0) + 1;
}
}
// 找出最大出现次数
const counts = Object.values(typeCount);
const max = counts.length > 0 ? Math.max(...counts) : 0;
console.log(max);
代码详细解析
输入处理:
fs.readFileSync(0)
读取输入流。split(/\s+/)
按空格分割输入字符串。- 解析前两个参数为
c
和b
,剩余参数转为整数数组。
字节和计算:
(num >> 24) & 0xff
:右移24位获取最高位字节。(num >> 16) & 0xff
:右移16位获取第二个字节。(num >> 8) & 0xff
:右移8位获取第三个字节。num & 0xff
:直接取最低位字节。
模运算与分类:
- 计算四个字节之和
sum
。 sum % b
计算模结果。- 若模结果
< c
则记录到typeCount
对象。
- 计算四个字节之和
统计与输出:
Object.values(typeCount)
获取所有有效类型的出现次数。- 找出最大值,若无效则输出0。
示例测试
示例1输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
解析:
- 256的字节和为1 → 1%4=1(有效)。
- 有效类型0、1、2中,类型1和2各出现3次。
示例2输入:
5 3 1 2 3 4 5 6 7 8 9 10
输出:
10
解析:
- 所有模结果均小于5,所有类型有效,最大值10。
示例3输入:
0 1 100 200 300 400 500 600 700 800 900 1000
输出:
0
解析:
c=0
,所有模结果非负,均无效。
综合分析
- 时间复杂度:O(n),其中n=10,每个数处理时间为O(1)。
- 空间复杂度:O(k),k为有效类型数量(最多为b)。
- 优势:
- 位运算高效:直接通过位移和掩码提取字节,无需类型转换。
- 哈希表快速统计:对象操作时间复杂度为O(1)。
- 适用场景:适用于大规模整数处理,满足时间与空间要求。
C++
问题分析
我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。
解题思路
- 输入处理:读取
c
、b
和10个待分类的整数。 - 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
- 模运算与分类:计算字节和对
b
取模,判断是否小于c
,记录有效类型。 - 统计与输出:统计有效类型的出现次数,输出最大值。
代码实现
#include <iostream>
#include <unordered_map>
#include <vector>
using namespace std;
int main() {
int c, b;
vector<int> nums(10);
// 读取输入:前两个参数为c和b,剩余10个为待处理整数
cin >> c >> b;
for (int i = 0; i < 10; ++i) {
cin >> nums[i];
}
unordered_map<int, int> type_count; // 记录有效类型及其出现次数
for (int num : nums) {
unsigned unum = num; // 转换为无符号类型,避免符号扩展问题
int sum = 0;
sum += (unum >> 24) & 0xFF; // 提取最高位字节(第4个字节)
sum += (unum >> 16) & 0xFF; // 提取第3个字节
sum += (unum >> 8) & 0xFF; // 提取第2个字节
sum += unum & 0xFF; // 提取最低位字节(第1个字节)
int mod = sum % b; // 计算模结果
if (mod < c) { // 判断是否为有效类型
type_count[mod]++;
}
}
// 找出出现次数最多的类型
int max_count = 0;
for (const auto& pair : type_count) {
if (pair.second > max_count) {
max_count = pair.second;
}
}
cout << max_count << endl;
return 0;
}
代码详细解析
输入处理:
cin
读取输入,前两个值为c
和b
,后续为10个整数。- 使用
vector<int>
存储待处理的整数。
字节和计算:
unum = num
:将数值转换为无符号类型,避免右移时的符号扩展问题。(unum >> 24) & 0xFF
:右移24位获取最高位字节(第4个字节)。(unum >> 16) & 0xFF
:右移16位获取第3个字节。(unum >> 8) & 0xFF
:右移8位获取第2个字节。unum & 0xFF
:直接取最低位字节(第1个字节)。
模运算与分类:
sum % b
:计算四个字节之和的模结果。if (mod < c)
:判断是否为有效类型,并更新哈希表type_count
。
统计结果:
- 遍历哈希表,找到出现次数最多的类型,输出其出现次数。
示例测试
示例1输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
解析:
- 256的四个字节和为
0+0+1+0=1
→1%4=1
(有效)。 - 有效类型为0、1、2,类型1和2各出现3次。
示例2输入:
5 3 1 2 3 4 5 6 7 8 9 10
输出:
10
解析:
- 所有数的模结果均小于5,有效类型出现次数最大为10。
示例3输入:
0 1 100 200 300 400 500 600 700 800 900 1000
输出:
0
解析:
c=0
,所有模结果非负,均无效。
综合分析
时间复杂度:O(1)
- 每个整数处理时间为常数,总共有10个整数,总时间复杂度为 O(10) = O(1)。
空间复杂度:O(1)
- 哈希表最多存储
b
个键值对,但b
的范围由输入决定,实际中可视为常数。
- 哈希表最多存储
优势:
- 位运算高效:通过位移和掩码快速提取字节值,时间复杂度稳定。
- 哈希表快速统计:
unordered_map
的插入和查询操作平均为 O(1) 时间复杂度。
适用场景:
- 适用于需要快速处理整数分类的场景,如网络协议解析、数据特征提取等。
C语言
问题分析
我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。
解题思路
- 输入处理:读取
c
、b
和10个待分类的整数。 - 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
- 模运算与分类:计算字节和对
b
取模,判断是否小于c
,记录有效类型。 - 统计与输出:统计有效类型的出现次数,输出最大值。
代码实现
#include <stdio.h>
#include <stdlib.h>
int main() {
int c, b;
int nums[10];
// 读取输入参数
scanf("%d %d", &c, &b);
for (int i = 0; i < 10; i++) {
scanf("%d", &nums[i]);
}
// 处理特殊情况:c ≤ 0时所有类型无效
if (c <= 0) {
printf("0\n");
return 0;
}
// 动态分配数组记录有效类型的出现次数
int *count = (int *)calloc(b, sizeof(int));
if (count == NULL) {
printf("0\n");
return 0;
}
// 处理每个数字
for (int i = 0; i < 10; i++) {
unsigned num = (unsigned)nums[i]; // 转为无符号数处理
// 提取四个字节的十进制值
int byte1 = (num >> 24) & 0xFF; // 最高位字节
int byte2 = (num >> 16) & 0xFF;
int byte3 = (num >> 8) & 0xFF;
int byte4 = num & 0xFF; // 最低位字节
int sum = byte1 + byte2 + byte3 + byte4;
int mod = sum % b; // 计算模结果
if (mod < c) { // 判断有效性
count[mod]++; // 统计有效类型
}
}
// 遍历数组找出最大出现次数
int max_count = 0;
for (int i = 0; i < b; i++) {
if (count[i] > max_count) {
max_count = count[i];
}
}
// 输出结果并释放内存
printf("%d\n", max_count);
free(count);
return 0;
}
代码详细解析
- 输入处理:
scanf
读取前两个参数c
和b
,后续读取10个整数存入数组nums
。
- 特殊处理:
- 若
c <= 0
,直接输出0,因为所有模结果均无效。
- 若
- 动态数组分配:
- 使用
calloc
分配大小为b
的数组count
,初始化为0,用于记录每个有效类型的出现次数。
- 使用
- 字节分解与求和:
- 将整数转为无符号数处理,避免符号扩展问题。
- 通过位操作提取四个字节的值,计算它们的十进制和。
- 模运算与分类:
- 计算总和对
b
取模,若结果小于c
,则在count
数组中对应位置计数加1。
- 计算总和对
- 统计结果:
- 遍历
count
数组,找到出现次数的最大值并输出。
- 遍历
示例测试
示例1输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
解析:
- 有效类型为0、1、2,类型1和2各出现3次。
示例2输入:
5 3 1 2 3 4 5 6 7 8 9 10
输出:
10
解析:
- 所有模结果均小于5,有效类型出现次数最大为10。
示例3输入:
0 1 100 200 300 400 500 600 700 800 900 1000
输出:
0
解析:
c=0
,所有模结果均无效,输出0。
综合分析
- 时间复杂度:O(1)
- 每个整数处理时间为常数,总共有10个整数,时间复杂度为 O(10) = O(1)。
- 空间复杂度:O(b)
- 使用动态数组
count
记录有效类型次数,数组大小为b
。
- 使用动态数组
- 优势:
- 位运算高效:通过无符号转换和位操作快速提取字节值。
- 动态内存管理:灵活处理不同规模的
b
,避免内存浪费。
- 适用场景:
- 适用于需要快速处理整数分类的场景,如网络协议解析、数据特征提取等。
GO
问题分析
我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。
解题思路
- 输入处理:读取
c
、b
和10个待分类的整数。 - 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
- 模运算与分类:计算字节和对
b
取模,判断是否小于c
,记录有效类型。 - 统计与输出:统计有效类型的出现次数,输出最大值。
代码实现
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"strings"
)
func main() {
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
input := strings.TrimSpace(scanner.Text())
parts := strings.Fields(input)
// 解析输入参数
c, _ := strconv.Atoi(parts[0])
b, _ := strconv.Atoi(parts[1])
nums := parts[2:12]
// 处理无效的 c
if c <= 0 {
fmt.Println(0)
return
}
typeCount := make(map[int]int) // 记录有效类型的出现次数
// 处理每个数字
for _, s := range nums {
num, _ := strconv.Atoi(s)
u := uint32(num) // 转换为无符号数处理负数
// 提取四个字节的十进制值
byte1 := (u >> 24) & 0xFF // 最高位字节
byte2 := (u >> 16) & 0xFF
byte3 := (u >> 8) & 0xFF
byte4 := u & 0xFF
sum := int(byte1 + byte2 + byte3 + byte4)
mod := sum % b // 计算模结果
if mod < c { // 判断是否有效
typeCount[mod]++
}
}
// 找出最大出现次数
maxCount := 0
for _, count := range typeCount {
if count > maxCount {
maxCount = count
}
}
fmt.Println(maxCount)
}
代码详细解析
输入处理:
bufio.Scanner
读取输入并分割为字符串数组。- 第一个元素为
c
,第二个为b
,剩余10个为待处理整数。
无效类型处理:
- 若
c <= 0
,直接输出0,因为所有模结果均无效。
- 若
字节分解与求和:
uint32(num)
:将整数转为无符号类型,避免符号扩展问题。(u >> 24) & 0xFF
:提取最高位字节(第4个字节)。(u >> 16) & 0xFF
:提取第3个字节。(u >> 8) & 0xFF
:提取第2个字节。u & 0xFF
:提取最低位字节(第1个字节)。
模运算与分类:
sum % b
:计算总和对b
取模。mod < c
:判断是否为有效类型,并记录到typeCount
。
统计结果:
- 遍历哈希表
typeCount
,找到出现次数最多的有效类型。
- 遍历哈希表
示例测试
示例1输入:
3 4 256 257 258 259 260 261 262 263 264 265
输出:
3
解析:
- 256的四个字节和为
0+0+1+0=1
→1%4=1
(有效)。 - 有效类型为0、1、2,类型1和2各出现3次。
示例2输入:
5 3 1 2 3 4 5 6 7 8 9 10
输出:
10
解析:
- 所有数的模结果均小于5,有效类型出现次数最大为10。
示例3输入:
0 1 100 200 300 400 500 600 700 800 900 1000
输出:
0
解析:
c=0
,所有模结果均无效,输出0。
综合分析
- 时间复杂度:O(1)
- 每个整数处理时间为常数,总共有10个整数,时间复杂度为 O(10) = O(1)。
- 空间复杂度:O(1)
- 哈希表最多存储
b
个键值对,但b
的范围由输入决定,实际中可视为常数。
- 哈希表最多存储
- 优势:
- 位运算高效:通过位移和掩码快速提取字节值。
- 哈希表快速统计:
map[int]int
的插入和查询操作平均为 O(1)。
- 适用场景:
- 适用于需要快速处理整数分类的场景,如网络协议解析、数据特征提取等。
更多内容:
https://www.kdocs.cn/l/cvk0eoGYucWA
本文发表于【纪元A梦】,关注我,获取更多实用教程/资源!