当前位置: 首页 > article >正文

【2024年华为OD机试】(B卷,100分)- 数据分类 (Java JS PythonC/C++)

在这里插入图片描述

一、问题描述

题目描述

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

此数据a(四个字节大小)的四个字节相加对一个给定的值b取模,如果得到的结果小于一个给定的值c,则数据a为有效类型,其类型为取模的值;如果得到的结果大于或者等于c,则数据a为无效类型。

比如一个数据a=0x01010101,b=3,按照分类方法计算(0x01+0x01+0x01+0x01)%3=1,

所以如果c=2,则此a为有效类型,其类型为1,如果c=1,则此a为无效类型;

又比如一个数据a=0x01010103,b=3,按照分类方法计算(0x01+0x01+0x01+0x03)%3=0,

所以如果c=2,则此a为有效类型,其类型为0,如果c=0,则此a为无效类型。

输入12个数据,第一个数据为c,第二个数据为b,剩余10个数据为需要分类的数据,

请找到有效类型中包含数据最多的类型,并输出该类型含有多少个数据。

输入描述

输入12个数据,用空格分隔,第一个数据为c,第二个数据为b,剩余10个数据为需要分类的数据。

输出描述

输出最多数据的有效类型有多少个数据。

用例

用例1

输入

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

输出

3

说明
10个数据4个字节相加后的结果分别为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个数据,类型为0的只有2个数据,故输出3。

用例2

输入

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

输出

2

说明
10个数据4个字节相加后的结果分别为1 2 3 4 5 6 7 8 9 10,

故对4取模的结果为1 2 3 0 1 2 3 0 1 2,c为1,

所以只有0是有效类型,类型为0的有2个数据,故输出2。

题目解析

考察点

考察基本的逻辑处理和数据分类。

解析思路

  1. 读取输入
    • 读取第一个数据c和第二个数据b。
    • 读取剩余的10个数据,这些数据需要进行分类。
  2. 分类处理
    • 对于每个数据,将其转换为四个字节,并计算这四个字节的和。
    • 对这个和对b取模,得到的结果即为该数据的类型。
    • 检查这个类型是否小于c,如果是,则该数据为有效类型。
  3. 统计有效类型
    • 使用一个字典或数组来记录每个有效类型的出现次数。
    • 遍历所有数据,更新每个有效类型的计数。
  4. 找到最多数据的有效类型
    • 遍历记录有效类型出现次数的字典或数组,找到出现次数最多的有效类型。
    • 输出这个类型的数据个数。

注意事项

  • 数据处理:确保正确处理每个数据的四个字节,计算字节和时要注意数据类型转换。
  • 类型判断:正确判断每个数据的类型是否有效,即是否小于c。
  • 统计方法:使用合适的数据结构(如字典或数组)来统计每个有效类型的出现次数,确保统计过程的效率。
  • 输出结果:输出最多数据的有效类型的数据个数,注意处理多个类型出现次数相同的情况。

二、JavaScript算法源码

以下是 JavaScript 代码的详细中文注释和讲解:


JavaScript 代码

/* JavaScript Node ACM模式 控制台输入获取 */
const readline = require("readline");

// 创建 readline 接口,用于从控制台读取输入
const rl = readline.createInterface({
  input: process.stdin,  // 输入流
  output: process.stdout, // 输出流
});

// 监听每一行输入
rl.on("line", (line) => {
  // 将输入行按空格分割为数组
  let arr = line.split(" ");

  // 提取数组中的第一个元素作为 c,并将其转换为数字
  const c = arr.shift() - 0;
  // 提取数组中的第二个元素作为 b,并将其转换为数字
  const b = arr.shift() - 0;

  // 调用 getResult 函数并输出结果
  console.log(getResult(arr, c, b));
});

/**
 * 计算满足条件的类型数量
 * @param arr 输入的数组
 * @param c 类型上限
 * @param b 模数
 * @return 返回满足条件的类型数量的最大值
 */
function getResult(arr, c, b) {
  // 使用对象 count 记录每种类型的数量
  const count = {};

  arr
    .map((a) => {
      // 将数组中的每个元素转换为十六进制字符串
      let str = Number(a).toString(16);

      // 如果十六进制字符串长度为奇数,前面补零
      if (str.length % 2 !== 0) {
        str = "0" + str;
      }

      // 计算十六进制字符串每两位的和
      let sum = 0;
      for (let i = 0; i < str.length - 1; i += 2) {
        sum += parseInt(str.slice(i, i + 2), 16);
      }

      // 计算 sum 模 b 的余数,作为类型
      const type = sum % b;

      // 如果类型小于 c,返回类型;否则返回 -1
      if (type < c) {
        return type;
      } else {
        return -1;
      }
    })
    .forEach((type) => {
      // 如果类型不为 -1,记录该类型的数量
      if (type !== -1) {
        count[type] ? count[type]++ : (count[type] = 1);
      }
    });

  // 返回 count 对象中值的最大值
  return Object.values(count).sort((a, b) => b - a)[0];
}

详细讲解


1. 输入处理
const readline = require("readline");

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
});

rl.on("line", (line) => {
  let arr = line.split(" ");

  const c = arr.shift() - 0;
  const b = arr.shift() - 0;

  console.log(getResult(arr, c, b));
});
  • 功能:
    • 使用 readline 模块从控制台读取输入。
    • 每读取一行输入,将其按空格分割为数组 arr
    • 提取数组中的前两个元素作为 cb,并将其转换为数字。
    • 调用 getResult 函数并输出结果。

2. 核心函数 getResult
function getResult(arr, c, b) {
  const count = {};

  arr
    .map((a) => {
      let str = Number(a).toString(16);

      if (str.length % 2 !== 0) {
        str = "0" + str;
      }

      let sum = 0;
      for (let i = 0; i < str.length - 1; i += 2) {
        sum += parseInt(str.slice(i, i + 2), 16);
      }

      const type = sum % b;

      if (type < c) {
        return type;
      } else {
        return -1;
      }
    })
    .forEach((type) => {
      if (type !== -1) {
        count[type] ? count[type]++ : (count[type] = 1);
      }
    });

  return Object.values(count).sort((a, b) => b - a)[0];
}
  • 功能:
    • 计算满足条件的类型数量,并返回最大值。
  • 算法逻辑:
    1. 使用对象 count 记录每种类型的数量。
    2. 遍历数组 arr,对每个元素进行以下操作:
      • 将其转换为十六进制字符串。
      • 如果字符串长度为奇数,前面补零。
      • 计算每两位的和 sum
      • 计算 sumb 的余数 type
      • 如果 type 小于 c,返回 type;否则返回 -1
    3. 遍历结果数组,记录每种类型的数量。
    4. 返回 count 对象中值的最大值。

代码运行示例

示例 1:

输入:

3 5
10 20 30

输出:

2

解释:

  • 对于 10
    • 十六进制为 a,补零后为 0a
    • 和为 0 + 10 = 10
    • 类型为 10 % 5 = 0
  • 对于 20
    • 十六进制为 14
    • 和为 1 + 4 = 5
    • 类型为 5 % 5 = 0
  • 对于 30
    • 十六进制为 1e
    • 和为 1 + 14 = 15
    • 类型为 15 % 5 = 0
  • 类型 0 的数量为 3,但 c = 3,所以最大值为 3

示例 2:

输入:

2 4
5 15

输出:

1

解释:

  • 对于 5
    • 十六进制为 5,补零后为 05
    • 和为 0 + 5 = 5
    • 类型为 5 % 4 = 1
  • 对于 15
    • 十六进制为 f,补零后为 0f
    • 和为 0 + 15 = 15
    • 类型为 15 % 4 = 3
  • 类型 13 的数量均为 1,最大值为 1

总结

  1. 功能:
    • 计算满足条件的类型数量,并返回最大值。
  2. 优点:
    • 使用十六进制转换和模运算快速计算类型。
    • 使用对象记录类型数量,方便统计。
  3. 适用场景:
    • 适用于需要根据特定规则计算类型数量的场景。

如果您有其他问题,欢迎随时提问!

三、Java算法源码

以下是 Java 代码的详细中文注释和讲解:


Java 代码

import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
  // 输入获取
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);

    // 读取输入的两个整数 c 和 b
    int c = sc.nextInt();
    int b = sc.nextInt();

    // 读取输入的数组 arr,固定长度为 10
    int[] arr = new int[10];
    for (int i = 0; i < 10; i++) arr[i] = sc.nextInt();

    // 调用 getResult 函数并输出结果
    System.out.println(getResult(c, b, arr));
  }

  // 算法入口
  public static int getResult(int c, int b, int[] arr) {
    // 使用 HashMap 记录每种类型的数量
    HashMap<Integer, Integer> count = new HashMap<>();

    // 对数组 arr 中的每个元素进行处理
    Arrays.stream(arr)
        .map(
            a -> {
              // 将整数 a 转换为十六进制字符串
              String str = Integer.toHexString(a);

              // 如果十六进制字符串长度为奇数,前面补零
              if (str.length() % 2 != 0) {
                str = "0" + str;
              }

              // 计算十六进制字符串每两位的和
              int sum = 0;
              for (int i = 0; i < str.length() - 1; i += 2) {
                sum += Integer.parseInt(str.substring(i, i + 2), 16);
              }

              // 计算 sum 模 b 的余数,作为类型
              int t = sum % b;

              // 如果类型小于 c,返回类型;否则返回 -1
              if (t < c) {
                return t;
              } else {
                return -1;
              }
            })
        .forEach(
            t -> {
              // 如果类型不为 -1,记录该类型的数量
              if (t != -1) {
                count.put(t, count.getOrDefault(t, 0) + 1);
              }
            });

    // 返回 count 中值的最大值,如果没有满足条件的类型,返回 0
    return count.values().stream().max((x, y) -> x - y).orElse(0);
  }
}

详细讲解


1. 输入处理
public static void main(String[] args) {
  Scanner sc = new Scanner(System.in);

  // 读取输入的两个整数 c 和 b
  int c = sc.nextInt();
  int b = sc.nextInt();

  // 读取输入的数组 arr,固定长度为 10
  int[] arr = new int[10];
  for (int i = 0; i < 10; i++) arr[i] = sc.nextInt();

  // 调用 getResult 函数并输出结果
  System.out.println(getResult(c, b, arr));
}
  • 功能:
    • 使用 Scanner 从控制台读取输入。
    • 读取两个整数 cb
    • 读取长度为 10 的数组 arr
    • 调用 getResult 函数并输出结果。

2. 核心函数 getResult
public static int getResult(int c, int b, int[] arr) {
  // 使用 HashMap 记录每种类型的数量
  HashMap<Integer, Integer> count = new HashMap<>();

  // 对数组 arr 中的每个元素进行处理
  Arrays.stream(arr)
      .map(
          a -> {
            // 将整数 a 转换为十六进制字符串
            String str = Integer.toHexString(a);

            // 如果十六进制字符串长度为奇数,前面补零
            if (str.length() % 2 != 0) {
              str = "0" + str;
            }

            // 计算十六进制字符串每两位的和
            int sum = 0;
            for (int i = 0; i < str.length() - 1; i += 2) {
              sum += Integer.parseInt(str.substring(i, i + 2), 16);
            }

            // 计算 sum 模 b 的余数,作为类型
            int t = sum % b;

            // 如果类型小于 c,返回类型;否则返回 -1
            if (t < c) {
              return t;
            } else {
              return -1;
            }
          })
      .forEach(
          t -> {
            // 如果类型不为 -1,记录该类型的数量
            if (t != -1) {
              count.put(t, count.getOrDefault(t, 0) + 1);
            }
          });

  // 返回 count 中值的最大值,如果没有满足条件的类型,返回 0
  return count.values().stream().max((x, y) -> x - y).orElse(0);
}
  • 功能:
    • 计算满足条件的类型数量,并返回最大值。
  • 算法逻辑:
    1. 使用 HashMap 记录每种类型的数量。
    2. 遍历数组 arr,对每个元素进行以下操作:
      • 将其转换为十六进制字符串。
      • 如果字符串长度为奇数,前面补零。
      • 计算每两位的和 sum
      • 计算 sumb 的余数 t
      • 如果 t 小于 c,返回 t;否则返回 -1
    3. 遍历结果数组,记录每种类型的数量。
    4. 返回 count 中值的最大值,如果没有满足条件的类型,返回 0

代码运行示例

示例 1:

输入:

3 5
10 20 30 40 50 60 70 80 90 100

输出:

3

解释:

  • 对于 10
    • 十六进制为 a,补零后为 0a
    • 和为 0 + 10 = 10
    • 类型为 10 % 5 = 0
  • 对于 20
    • 十六进制为 14
    • 和为 1 + 4 = 5
    • 类型为 5 % 5 = 0
  • 对于 30
    • 十六进制为 1e
    • 和为 1 + 14 = 15
    • 类型为 15 % 5 = 0
  • 类型 0 的数量为 3,最大值为 3

示例 2:

输入:

2 4
5 15 25 35 45 55 65 75 85 95

输出:

1

解释:

  • 对于 5
    • 十六进制为 5,补零后为 05
    • 和为 0 + 5 = 5
    • 类型为 5 % 4 = 1
  • 对于 15
    • 十六进制为 f,补零后为 0f
    • 和为 0 + 15 = 15
    • 类型为 15 % 4 = 3
  • 类型 13 的数量均为 1,最大值为 1

总结

  1. 功能:
    • 计算满足条件的类型数量,并返回最大值。
  2. 优点:
    • 使用十六进制转换和模运算快速计算类型。
    • 使用 HashMap 记录类型数量,方便统计。
  3. 适用场景:
    • 适用于需要根据特定规则计算类型数量的场景。

如果您有其他问题,欢迎随时提问!

四、Python算法源码

以下是 Python 代码的详细中文注释和讲解:


Python 代码

# 输入获取
tmp = list(map(int, input().split()))  # 读取一行输入,按空格分割并转换为整数列表
c = tmp[0]  # 提取第一个元素作为 c
b = tmp[1]  # 提取第二个元素作为 b
arr = tmp[2:]  # 提取剩余元素作为数组 arr

# 判断是否有效
def classify(a):
    # 将整数 a 转换为十六进制字符串,并去除 '0x' 前缀
    s = hex(a)[2:]

    # 如果十六进制字符串长度为奇数,前面补零
    if len(s) % 2 != 0:
        s = "0" + s

    # 计算十六进制字符串每两位的和
    sumV = 0
    for i in range(0, len(s) - 1, 2):
        sumV += int(s[i:i + 2], 16)

    # 计算 sumV 模 b 的余数,作为类型
    t = sumV % b

    # 如果类型小于 c,返回类型;否则返回 -1
    if t < c:
        return t
    else:
        return -1

# 算法入口
def getResult():
    # 使用字典 count 记录每种类型的数量
    count = {}

    # 对数组 arr 中的每个元素调用 classify 函数,得到类型 t
    for t in map(classify, arr):
        # 如果类型 t 不为 -1,记录该类型的数量
        if t != -1:
            if count.get(t) is None:
                count[t] = 1
            else:
                count[t] += 1

    # 返回 count 中值的最大值
    return max(count.values())

# 算法调用
print(getResult())

详细讲解


1. 输入处理
tmp = list(map(int, input().split()))  # 读取一行输入,按空格分割并转换为整数列表
c = tmp[0]  # 提取第一个元素作为 c
b = tmp[1]  # 提取第二个元素作为 b
arr = tmp[2:]  # 提取剩余元素作为数组 arr
  • 功能:
    • 使用 input().split() 读取一行输入,按空格分割为字符串列表。
    • 使用 map(int, ...) 将字符串列表转换为整数列表 tmp
    • 提取 tmp 中的前两个元素作为 cb
    • 提取剩余元素作为数组 arr

2. 核心函数 classify
def classify(a):
    # 将整数 a 转换为十六进制字符串,并去除 '0x' 前缀
    s = hex(a)[2:]

    # 如果十六进制字符串长度为奇数,前面补零
    if len(s) % 2 != 0:
        s = "0" + s

    # 计算十六进制字符串每两位的和
    sumV = 0
    for i in range(0, len(s) - 1, 2):
        sumV += int(s[i:i + 2], 16)

    # 计算 sumV 模 b 的余数,作为类型
    t = sumV % b

    # 如果类型小于 c,返回类型;否则返回 -1
    if t < c:
        return t
    else:
        return -1
  • 功能:
    • 对输入的整数 a 进行处理,计算其类型。
  • 算法逻辑:
    1. 将整数 a 转换为十六进制字符串,并去除 0x 前缀。
    2. 如果字符串长度为奇数,前面补零。
    3. 计算每两位的和 sumV
    4. 计算 sumVb 的余数 t
    5. 如果 t 小于 c,返回 t;否则返回 -1

3. 核心函数 getResult
def getResult():
    # 使用字典 count 记录每种类型的数量
    count = {}

    # 对数组 arr 中的每个元素调用 classify 函数,得到类型 t
    for t in map(classify, arr):
        # 如果类型 t 不为 -1,记录该类型的数量
        if t != -1:
            if count.get(t) is None:
                count[t] = 1
            else:
                count[t] += 1

    # 返回 count 中值的最大值
    return max(count.values())
  • 功能:
    • 计算满足条件的类型数量,并返回最大值。
  • 算法逻辑:
    1. 使用字典 count 记录每种类型的数量。
    2. 遍历数组 arr,对每个元素调用 classify 函数,得到类型 t
    3. 如果类型 t 不为 -1,记录该类型的数量。
    4. 返回 count 中值的最大值。

4. 算法调用
print(getResult())
  • 功能:
    • 调用 getResult 函数并输出结果。

代码运行示例

示例 1:

输入:

3 5 10 20 30 40 50 60 70 80 90 100

输出:

3

解释:

  • 对于 10
    • 十六进制为 a,补零后为 0a
    • 和为 0 + 10 = 10
    • 类型为 10 % 5 = 0
  • 对于 20
    • 十六进制为 14
    • 和为 1 + 4 = 5
    • 类型为 5 % 5 = 0
  • 对于 30
    • 十六进制为 1e
    • 和为 1 + 14 = 15
    • 类型为 15 % 5 = 0
  • 类型 0 的数量为 3,最大值为 3

示例 2:

输入:

2 4 5 15 25 35 45 55 65 75 85 95

输出:

1

解释:

  • 对于 5
    • 十六进制为 5,补零后为 05
    • 和为 0 + 5 = 5
    • 类型为 5 % 4 = 1
  • 对于 15
    • 十六进制为 f,补零后为 0f
    • 和为 0 + 15 = 15
    • 类型为 15 % 4 = 3
  • 类型 13 的数量均为 1,最大值为 1

总结

  1. 功能:
    • 计算满足条件的类型数量,并返回最大值。
  2. 优点:
    • 使用十六进制转换和模运算快速计算类型。
    • 使用字典记录类型数量,方便统计。
  3. 适用场景:
    • 适用于需要根据特定规则计算类型数量的场景。

如果您有其他问题,欢迎随时提问!

五、C/C++算法源码:

以下是 C++C 语言的代码实现,包含详细的中文注释和讲解:


C++ 代码

#include <iostream>
#include <vector>
#include <map>
#include <algorithm>
using namespace std;

// 判断是否有效
int classify(int a, int b, int c) {
    // 将整数 a 转换为十六进制字符串
    char hexStr[20];
    sprintf(hexStr, "%x", a);  // 使用 sprintf 将整数转换为十六进制字符串

    string s = hexStr;

    // 如果十六进制字符串长度为奇数,前面补零
    if (s.length() % 2 != 0) {
        s = "0" + s;
    }

    // 计算十六进制字符串每两位的和
    int sumV = 0;
    for (int i = 0; i < s.length() - 1; i += 2) {
        string sub = s.substr(i, 2);  // 提取两位十六进制字符
        sumV += stoi(sub, nullptr, 16);  // 将十六进制字符串转换为整数并累加
    }

    // 计算 sumV 模 b 的余数,作为类型
    int t = sumV % b;

    // 如果类型小于 c,返回类型;否则返回 -1
    if (t < c) {
        return t;
    } else {
        return -1;
    }
}

// 算法入口
int getResult(vector<int>& arr, int b, int c) {
    map<int, int> count;  // 使用 map 记录每种类型的数量

    // 对数组 arr 中的每个元素调用 classify 函数,得到类型 t
    for (int a : arr) {
        int t = classify(a, b, c);

        // 如果类型 t 不为 -1,记录该类型的数量
        if (t != -1) {
            count[t]++;
        }
    }

    // 返回 count 中值的最大值
    int maxCount = 0;
    for (auto& pair : count) {
        if (pair.second > maxCount) {
            maxCount = pair.second;
        }
    }

    return maxCount;
}

int main() {
    // 输入获取
    vector<int> tmp;
    int num;
    while (cin >> num) {
        tmp.push_back(num);
    }

    int c = tmp[0];  // 提取第一个元素作为 c
    int b = tmp[1];  // 提取第二个元素作为 b
    vector<int> arr(tmp.begin() + 2, tmp.end());  // 提取剩余元素作为数组 arr

    // 算法调用
    cout << getResult(arr, b, c) << endl;

    return 0;
}

C 语言代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 判断是否有效
int classify(int a, int b, int c) {
    // 将整数 a 转换为十六进制字符串
    char hexStr[20];
    sprintf(hexStr, "%x", a);  // 使用 sprintf 将整数转换为十六进制字符串

    // 如果十六进制字符串长度为奇数,前面补零
    if (strlen(hexStr) % 2 != 0) {
        memmove(hexStr + 1, hexStr, strlen(hexStr) + 1);  // 右移一位
        hexStr[0] = '0';  // 补零
    }

    // 计算十六进制字符串每两位的和
    int sumV = 0;
    for (int i = 0; i < strlen(hexStr) - 1; i += 2) {
        char sub[3];
        strncpy(sub, hexStr + i, 2);  // 提取两位十六进制字符
        sub[2] = '\0';  // 添加字符串结束符
        sumV += (int)strtol(sub, NULL, 16);  // 将十六进制字符串转换为整数并累加
    }

    // 计算 sumV 模 b 的余数,作为类型
    int t = sumV % b;

    // 如果类型小于 c,返回类型;否则返回 -1
    if (t < c) {
        return t;
    } else {
        return -1;
    }
}

// 算法入口
int getResult(int* arr, int n, int b, int c) {
    int count[100] = {0};  // 使用数组记录每种类型的数量,假设类型不超过 100

    // 对数组 arr 中的每个元素调用 classify 函数,得到类型 t
    for (int i = 0; i < n; i++) {
        int t = classify(arr[i], b, c);

        // 如果类型 t 不为 -1,记录该类型的数量
        if (t != -1) {
            count[t]++;
        }
    }

    // 返回 count 中值的最大值
    int maxCount = 0;
    for (int i = 0; i < 100; i++) {
        if (count[i] > maxCount) {
            maxCount = count[i];
        }
    }

    return maxCount;
}

int main() {
    // 输入获取
    int tmp[100];
    int n = 0;
    while (scanf("%d", &tmp[n]) != EOF) {
        n++;
    }

    int c = tmp[0];  // 提取第一个元素作为 c
    int b = tmp[1];  // 提取第二个元素作为 b
    int arr[100];
    for (int i = 2; i < n; i++) {
        arr[i - 2] = tmp[i];  // 提取剩余元素作为数组 arr
    }

    // 算法调用
    printf("%d\n", getResult(arr, n - 2, b, c));

    return 0;
}

详细讲解


1. 输入处理
  • C++:

    vector<int> tmp;
    int num;
    while (cin >> num) {
        tmp.push_back(num);
    }
    int c = tmp[0];
    int b = tmp[1];
    vector<int> arr(tmp.begin() + 2, tmp.end());
    
    • 使用 vector 动态存储输入数据。
    • 提取前两个元素作为 cb,剩余元素作为数组 arr
  • C:

    int tmp[100];
    int n = 0;
    while (scanf("%d", &tmp[n]) != EOF) {
        n++;
    }
    int c = tmp[0];
    int b = tmp[1];
    int arr[100];
    for (int i = 2; i < n; i++) {
        arr[i - 2] = tmp[i];
    }
    
    • 使用固定大小的数组 tmp 存储输入数据。
    • 提取前两个元素作为 cb,剩余元素作为数组 arr

2. 核心函数 classify
  • C++:

    int classify(int a, int b, int c) {
        char hexStr[20];
        sprintf(hexStr, "%x", a);
        string s = hexStr;
        if (s.length() % 2 != 0) {
            s = "0" + s;
        }
        int sumV = 0;
        for (int i = 0; i < s.length() - 1; i += 2) {
            string sub = s.substr(i, 2);
            sumV += stoi(sub, nullptr, 16);
        }
        int t = sumV % b;
        if (t < c) {
            return t;
        } else {
            return -1;
        }
    }
    
    • 将整数 a 转换为十六进制字符串。
    • 如果字符串长度为奇数,前面补零。
    • 计算每两位的和 sumV
    • 计算 sumVb 的余数 t
    • 如果 t 小于 c,返回 t;否则返回 -1
  • C:

    int classify(int a, int b, int c) {
        char hexStr[20];
        sprintf(hexStr, "%x", a);
        if (strlen(hexStr) % 2 != 0) {
            memmove(hexStr + 1, hexStr, strlen(hexStr) + 1);
            hexStr[0] = '0';
        }
        int sumV = 0;
        for (int i = 0; i < strlen(hexStr) - 1; i += 2) {
            char sub[3];
            strncpy(sub, hexStr + i, 2);
            sub[2] = '\0';
            sumV += (int)strtol(sub, NULL, 16);
        }
        int t = sumV % b;
        if (t < c) {
            return t;
        } else {
            return -1;
        }
    }
    
    • 逻辑与 C++ 版本相同,但使用 C 标准库函数实现。

3. 核心函数 getResult
  • C++:

    int getResult(vector<int>& arr, int b, int c) {
        map<int, int> count;
        for (int a : arr) {
            int t = classify(a, b, c);
            if (t != -1) {
                count[t]++;
            }
        }
        int maxCount = 0;
        for (auto& pair : count) {
            if (pair.second > maxCount) {
                maxCount = pair.second;
            }
        }
        return maxCount;
    }
    
    • 使用 map 记录每种类型的数量。
    • 遍历数组 arr,调用 classify 函数,记录类型数量。
    • 返回类型数量的最大值。
  • C:

    int getResult(int* arr, int n, int b, int c) {
        int count[100] = {0};
        for (int i = 0; i < n; i++) {
            int t = classify(arr[i], b, c);
            if (t != -1) {
                count[t]++;
            }
        }
        int maxCount = 0;
        for (int i = 0; i < 100; i++) {
            if (count[i] > maxCount) {
                maxCount = count[i];
            }
        }
        return maxCount;
    }
    
    • 使用固定大小的数组 count 记录类型数量。
    • 遍历数组 arr,调用 classify 函数,记录类型数量。
    • 返回类型数量的最大值。

4. 算法调用
  • C++:
    cout << getResult(arr, b, c) << endl;
    
  • C:
    printf("%d\n", getResult(arr, n - 2, b, c));
    

总结

  1. 功能:
    • 计算满足条件的类型数量,并返回最大值。
  2. 优点:
    • 使用十六进制转换和模运算快速计算类型。
    • 使用 map(C++)或数组(C)记录类型数量,方便统计。
  3. 适用场景:
    • 适用于需要根据特定规则计算类型数量的场景。

如果您有其他问题,欢迎随时提问!

六、尾言

什么是华为OD?

华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。

为什么刷题很重要?

  1. 机试是进入技术面的第一关:
    华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。

  2. 技术面试需要手撕代码:
    技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。

  3. 入职后的可信考试:
    入职华为后,还需要通过“可信考试”。可信考试分为三个等级:

    • 入门级:主要考察基础算法与编程能力。
    • 工作级:更贴近实际业务需求,可能涉及复杂的算法或与工作内容相关的场景题目。
    • 专业级:最高等级,考察深层次的算法以及优化能力,与薪资直接挂钩。

刷题策略与说明:

2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:

  1. 关注历年真题:

    • 题库中的旧题占比较大,建议优先刷历年的A卷、B卷、C卷、D卷题目。
    • 对于每道题目,建议深度理解其解题思路、代码实现,以及相关算法的适用场景。
  2. 适应新题目:

    • E卷中包含全新题目,需要掌握全面的算法知识和一定的灵活应对能力。
    • 建议关注新的刷题平台或交流群,获取最新题目的解析和动态。
  3. 掌握常见算法:
    华为OD考试通常涉及以下算法和数据结构:

    • 排序算法(快速排序、归并排序等)
    • 动态规划(背包问题、最长公共子序列等)
    • 贪心算法
    • 栈、队列、链表的操作
    • 图论(最短路径、最小生成树等)
    • 滑动窗口、双指针算法
  4. 保持编程规范:

    • 注重代码的可读性和注释的清晰度。
    • 熟练使用常见编程语言,如C++、Java、Python等。

如何获取资源?

  1. 官方参考:

    • 华为招聘官网或相关的招聘平台会有一些参考信息。
    • 华为OD的相关公众号可能也会发布相关的刷题资料或学习资源。
  2. 加入刷题社区:

    • 找到可信的刷题交流群,与其他备考的小伙伴交流经验。
    • 关注知名的刷题网站,如LeetCode、牛客网等,这些平台上有许多华为OD的历年真题和解析。
  3. 寻找系统性的教程:

    • 学习一本经典的算法书籍,例如《算法导论》《剑指Offer》《编程之美》等。
    • 完成系统的学习课程,例如数据结构与算法的在线课程。

积极心态与持续努力:

刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。

考试注意细节

  1. 本地编写代码

    • 在本地 IDE(如 VS Code、PyCharm 等)上编写、保存和调试代码,确保逻辑正确后再复制粘贴到考试页面。这样可以减少语法错误,提高代码准确性。
  2. 调整心态,保持冷静

    • 遇到提示不足或实现不确定的问题时,不必慌张,可以采用更简单或更有把握的方法替代,确保思路清晰。
  3. 输入输出完整性

    • 注意训练和考试时都需要编写完整的输入输出代码,尤其是和题目示例保持一致。完成代码后务必及时调试,确保功能符合要求。
  4. 快捷键使用

    • 删除行可用 Ctrl+D,复制、粘贴和撤销分别为 Ctrl+CCtrl+VCtrl+Z,这些可以正常使用。
    • 避免使用 Ctrl+S,以免触发浏览器的保存功能。
  5. 浏览器要求

    • 使用最新版的 Google Chrome 浏览器完成考试,确保摄像头开启并正常工作。考试期间不要切换到其他网站,以免影响考试成绩。
  6. 交卷相关

    • 答题前,务必仔细查看题目示例,避免遗漏要求。
    • 每完成一道题后,点击【保存并调试】按钮,多次保存和调试是允许的,系统会记录得分最高的一次结果。完成所有题目后,点击【提交本题型】按钮。
    • 确保在考试结束前提交试卷,避免因未保存或调试失误而丢分。
  7. 时间和分数安排

    • 总时间:150 分钟;总分:400 分。
    • 试卷结构:2 道一星难度题(每题 100 分),1 道二星难度题(200 分)。及格分为 150 分。合理分配时间,优先完成自己擅长的题目。
  8. 考试环境准备

    • 考试前请备好草稿纸和笔。考试中尽量避免离开座位,确保监控画面正常。
    • 如需上厕所,请提前规划好时间以减少中途离开监控的可能性。
  9. 技术问题处理

    • 如果考试中遇到断电、断网、死机等技术问题,可以关闭浏览器并重新打开试卷链接继续作答。
    • 出现其他问题,请第一时间联系 HR 或监考人员进行反馈。

祝你考试顺利,取得理想成绩!


http://www.kler.cn/a/506172.html

相关文章:

  • 代理模式实现
  • Ansible自动化运维:基础与实践
  • SpringBoot集成Mongodb
  • 初始Java4
  • rsarsa-给定pqe求私钥对密文解密
  • jenkins-系统配置概述
  • 使用python+pytest+requests完成自动化接口测试(包括html报告的生成和日志记录以及层级的封装(包括调用Json文件))
  • 浅谈云计算14 | 云存储技术
  • Windows图形界面(GUI)-QT-C/C++ - QT 对话窗口
  • python flask简单实践
  • 谷歌浏览器的兼容性与性能优化策略
  • MySQL程序之:使用选项设置程序变量
  • 滚动字幕视频怎么制作
  • [Qt]窗口-QMainWindow类-QMenuBar、QToolBar、QStatusBar、QDockWidget控件
  • 运营媒体账号为什么需要住宅IP
  • 理解Spark中运行程序时数据被分区的过程
  • unity——Preject3——UI管理器
  • 【华为路由/交换机的ftp文件操作】
  • CSS的小知识
  • 蓝桥杯刷题第一天——判断闰年
  • 【k8s面试题2025】2、练气初期
  • 手摸手实战前端项目CI CD
  • 用 Python 自动化处理日常任务
  • 解决 chls.pro/ssl 无法进入问题
  • 【Rust自学】13.2. 闭包 Pt.2:闭包的类型推断和标注
  • 麒麟系统WPS提示字体缺失问题