华为OD机试真题——数据分类(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

发布于:2025-04-22 ⋅ 阅读:(17) ⋅ 点赞:(0)

在这里插入图片描述

2025 A卷 100分 题型

本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析;
并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式!

本文收录于专栏:《2025华为OD真题目录+全流程解析/备考攻略/经验分享

华为OD机试真题《数据分类》:



题目名称:数据分类


  • 知识点:位运算、逻辑处理
  • 时间限制:1秒
  • 空间限制:256MB
  • 限定语言:不限

题目描述

对一个数据 a 进行分类,分类方法为:

  1. a(四个字节大小)的四个字节的十进制值相加,得到一个总和。
  2. 将此总和对一个给定的值 b 取模。
  3. 若取模结果小于另一个给定值 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。


解题思路

  1. 输入处理:读取c、b和10个待分类的整数。
  2. 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
  3. 模运算与分类:计算字节和对b取模,判断是否小于c,记录有效类型。
  4. 统计与输出:统计有效类型的出现次数,输出最大值。

代码实现

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);
    }
}

代码详细解析

  1. 输入处理:使用Scanner读取输入并分割成字符串数组,解析出cb和10个整数。
  2. 字节和计算
    • 通过位运算(num >> n) & 0xFF依次提取四个字节的值。
    • 累加四个字节的十进制值得到总和。
  3. 模运算与分类:计算总和对b取模,若结果小于c则记录到哈希表中。
  4. 统计与输出:遍历哈希表的值,找到最大出现次数并输出。

示例测试

示例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,无有效类型。


综合分析

  1. 时间复杂度:O(n),其中n=10,每个数处理时间为常数。
  2. 空间复杂度:O(k),k为有效类型数量,最多为min(b, c)。
  3. 优势
    • 高效位运算:快速提取字节值,无需复杂转换。
    • 哈希表统计:O(1)时间记录和查询频率。
  4. 适用场景:适用于大范围整数分类,满足时间与空间要求。

python

问题分析

我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。


解题思路

  1. 输入处理:读取c、b和10个待分类的整数。
  2. 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
  3. 模运算与分类:计算字节和对b取模,判断是否小于c,记录有效类型。
  4. 统计与输出:统计有效类型的出现次数,输出最大值。

代码实现

# 读取输入并解析
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)

代码详细解析

  1. 输入处理

    • input().split() 读取输入并分割成字符串列表
    • map(int, ...) 转换为整数列表
    • 第一个元素为c,第二个为b,后续为待处理的10个整数
  2. 字节提取

    • (num >> 24) & 0xFF:右移24位获取最高位字节
    • (num >> 16) & 0xFF:右移16位获取第二个字节
    • (num >> 8) & 0xFF:右移8位获取第三个字节
    • num & 0xFF:直接取最低位字节
  3. 求和与分类

    • 计算四个字节之和 total
    • total % b 计算模结果
    • 若模结果 < c 则记录到字典 type_count
  4. 统计结果

    • 若字典非空则取最大值,否则输出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,均无效

综合分析

  1. 时间复杂度:O(n),其中n=10,每个数处理时间为O(1)
  2. 空间复杂度:O(k),k为有效类型数量(最多为b)
  3. 优势
    • 位运算高效:直接通过位移和掩码提取字节,无需类型转换
    • 哈希表快速统计:字典操作时间复杂度为O(1)
  4. 适用场景:适用于大规模整数处理,满足时间与空间要求

JavaScript

问题分析

我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。


解题思路

  1. 输入处理:读取 cb 和10个待分类的整数。
  2. 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
  3. 模运算与分类:计算字节和对 b 取模,判断是否小于 c,记录有效类型。
  4. 统计与输出:统计有效类型的出现次数,输出最大值。

代码实现

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);

代码详细解析

  1. 输入处理

    • fs.readFileSync(0) 读取输入流。
    • split(/\s+/) 按空格分割输入字符串。
    • 解析前两个参数为 cb,剩余参数转为整数数组。
  2. 字节和计算

    • (num >> 24) & 0xff:右移24位获取最高位字节。
    • (num >> 16) & 0xff:右移16位获取第二个字节。
    • (num >> 8) & 0xff:右移8位获取第三个字节。
    • num & 0xff:直接取最低位字节。
  3. 模运算与分类

    • 计算四个字节之和 sum
    • sum % b 计算模结果。
    • 若模结果 < c 则记录到 typeCount 对象。
  4. 统计与输出

    • 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,所有模结果非负,均无效。

综合分析

  1. 时间复杂度:O(n),其中n=10,每个数处理时间为O(1)。
  2. 空间复杂度:O(k),k为有效类型数量(最多为b)。
  3. 优势
    • 位运算高效:直接通过位移和掩码提取字节,无需类型转换。
    • 哈希表快速统计:对象操作时间复杂度为O(1)。
  4. 适用场景:适用于大规模整数处理,满足时间与空间要求。

C++

问题分析

我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。


解题思路

  1. 输入处理:读取 cb 和10个待分类的整数。
  2. 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
  3. 模运算与分类:计算字节和对 b 取模,判断是否小于 c,记录有效类型。
  4. 统计与输出:统计有效类型的出现次数,输出最大值。

代码实现

#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;
}

代码详细解析

  1. 输入处理

    • cin 读取输入,前两个值为 cb,后续为10个整数。
    • 使用 vector<int> 存储待处理的整数。
  2. 字节和计算

    • unum = num:将数值转换为无符号类型,避免右移时的符号扩展问题。
    • (unum >> 24) & 0xFF:右移24位获取最高位字节(第4个字节)。
    • (unum >> 16) & 0xFF:右移16位获取第3个字节。
    • (unum >> 8) & 0xFF:右移8位获取第2个字节。
    • unum & 0xFF:直接取最低位字节(第1个字节)。
  3. 模运算与分类

    • sum % b:计算四个字节之和的模结果。
    • if (mod < c):判断是否为有效类型,并更新哈希表 type_count
  4. 统计结果

    • 遍历哈希表,找到出现次数最多的类型,输出其出现次数。

示例测试

示例1输入:

3 4 256 257 258 259 260 261 262 263 264 265

输出

3

解析

  • 256的四个字节和为 0+0+1+0=11%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,所有模结果非负,均无效。

综合分析

  1. 时间复杂度:O(1)

    • 每个整数处理时间为常数,总共有10个整数,总时间复杂度为 O(10) = O(1)。
  2. 空间复杂度:O(1)

    • 哈希表最多存储 b 个键值对,但 b 的范围由输入决定,实际中可视为常数。
  3. 优势

    • 位运算高效:通过位移和掩码快速提取字节值,时间复杂度稳定。
    • 哈希表快速统计unordered_map 的插入和查询操作平均为 O(1) 时间复杂度。
  4. 适用场景

    • 适用于需要快速处理整数分类的场景,如网络协议解析、数据特征提取等。

C语言

问题分析

我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。


解题思路

  1. 输入处理:读取 cb 和10个待分类的整数。
  2. 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
  3. 模运算与分类:计算字节和对 b 取模,判断是否小于 c,记录有效类型。
  4. 统计与输出:统计有效类型的出现次数,输出最大值。

代码实现

#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;
}

代码详细解析

  1. 输入处理
    • scanf 读取前两个参数 cb,后续读取10个整数存入数组 nums
  2. 特殊处理
    • c <= 0,直接输出0,因为所有模结果均无效。
  3. 动态数组分配
    • 使用 calloc 分配大小为 b 的数组 count,初始化为0,用于记录每个有效类型的出现次数。
  4. 字节分解与求和
    • 将整数转为无符号数处理,避免符号扩展问题。
    • 通过位操作提取四个字节的值,计算它们的十进制和。
  5. 模运算与分类
    • 计算总和对 b 取模,若结果小于 c,则在 count 数组中对应位置计数加1。
  6. 统计结果
    • 遍历 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。

综合分析

  1. 时间复杂度:O(1)
    • 每个整数处理时间为常数,总共有10个整数,时间复杂度为 O(10) = O(1)。
  2. 空间复杂度:O(b)
    • 使用动态数组 count 记录有效类型次数,数组大小为 b
  3. 优势
    • 位运算高效:通过无符号转换和位操作快速提取字节值。
    • 动态内存管理:灵活处理不同规模的 b,避免内存浪费。
  4. 适用场景
    • 适用于需要快速处理整数分类的场景,如网络协议解析、数据特征提取等。

GO

问题分析

我们需要根据输入的整数数组进行分类,分类规则基于每个整数的四个字节之和的模运算结果。统计有效类型中出现次数最多的数据个数,若所有类型无效则输出0。


解题思路

  1. 输入处理:读取 cb 和10个待分类的整数。
  2. 字节和计算:将每个整数拆分为四个字节,计算各字节的十进制和。
  3. 模运算与分类:计算字节和对 b 取模,判断是否小于 c,记录有效类型。
  4. 统计与输出:统计有效类型的出现次数,输出最大值。

代码实现

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)
}

代码详细解析

  1. 输入处理

    • bufio.Scanner 读取输入并分割为字符串数组。
    • 第一个元素为 c,第二个为 b,剩余10个为待处理整数。
  2. 无效类型处理

    • c <= 0,直接输出0,因为所有模结果均无效。
  3. 字节分解与求和

    • uint32(num):将整数转为无符号类型,避免符号扩展问题。
    • (u >> 24) & 0xFF:提取最高位字节(第4个字节)。
    • (u >> 16) & 0xFF:提取第3个字节。
    • (u >> 8) & 0xFF:提取第2个字节。
    • u & 0xFF:提取最低位字节(第1个字节)。
  4. 模运算与分类

    • sum % b:计算总和对 b 取模。
    • mod < c:判断是否为有效类型,并记录到 typeCount
  5. 统计结果

    • 遍历哈希表 typeCount,找到出现次数最多的有效类型。

示例测试

示例1输入:

3 4 256 257 258 259 260 261 262 263 264 265

输出

3

解析

  • 256的四个字节和为 0+0+1+0=11%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。

综合分析

  1. 时间复杂度:O(1)
    • 每个整数处理时间为常数,总共有10个整数,时间复杂度为 O(10) = O(1)。
  2. 空间复杂度:O(1)
    • 哈希表最多存储 b 个键值对,但 b 的范围由输入决定,实际中可视为常数。
  3. 优势
    • 位运算高效:通过位移和掩码快速提取字节值。
    • 哈希表快速统计map[int]int 的插入和查询操作平均为 O(1)。
  4. 适用场景
    • 适用于需要快速处理整数分类的场景,如网络协议解析、数据特征提取等。

更多内容:

https://www.kdocs.cn/l/cvk0eoGYucWA

本文发表于【纪元A梦】,关注我,获取更多实用教程/资源!


网站公告

今日签到

点亮在社区的每一天
去签到