一、问题描述
题目描述
对一个数据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。
题目解析
考察点
考察基本的逻辑处理和数据分类。
解析思路
- 读取输入:
- 读取第一个数据c和第二个数据b。
- 读取剩余的10个数据,这些数据需要进行分类。
- 分类处理:
- 对于每个数据,将其转换为四个字节,并计算这四个字节的和。
- 对这个和对b取模,得到的结果即为该数据的类型。
- 检查这个类型是否小于c,如果是,则该数据为有效类型。
- 统计有效类型:
- 使用一个字典或数组来记录每个有效类型的出现次数。
- 遍历所有数据,更新每个有效类型的计数。
- 找到最多数据的有效类型:
- 遍历记录有效类型出现次数的字典或数组,找到出现次数最多的有效类型。
- 输出这个类型的数据个数。
注意事项
- 数据处理:确保正确处理每个数据的四个字节,计算字节和时要注意数据类型转换。
- 类型判断:正确判断每个数据的类型是否有效,即是否小于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
。 - 提取数组中的前两个元素作为
c
和b
,并将其转换为数字。 - 调用
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];
}
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 算法逻辑:
- 使用对象
count
记录每种类型的数量。 - 遍历数组
arr
,对每个元素进行以下操作:- 将其转换为十六进制字符串。
- 如果字符串长度为奇数,前面补零。
- 计算每两位的和
sum
。 - 计算
sum
模b
的余数type
。 - 如果
type
小于c
,返回type
;否则返回-1
。
- 遍历结果数组,记录每种类型的数量。
- 返回
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
。
- 十六进制为
- 类型
1
和3
的数量均为1
,最大值为1
。
总结
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 优点:
- 使用十六进制转换和模运算快速计算类型。
- 使用对象记录类型数量,方便统计。
- 适用场景:
- 适用于需要根据特定规则计算类型数量的场景。
如果您有其他问题,欢迎随时提问!
三、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
从控制台读取输入。 - 读取两个整数
c
和b
。 - 读取长度为
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);
}
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 算法逻辑:
- 使用
HashMap
记录每种类型的数量。 - 遍历数组
arr
,对每个元素进行以下操作:- 将其转换为十六进制字符串。
- 如果字符串长度为奇数,前面补零。
- 计算每两位的和
sum
。 - 计算
sum
模b
的余数t
。 - 如果
t
小于c
,返回t
;否则返回-1
。
- 遍历结果数组,记录每种类型的数量。
- 返回
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
。
- 十六进制为
- 类型
1
和3
的数量均为1
,最大值为1
。
总结
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 优点:
- 使用十六进制转换和模运算快速计算类型。
- 使用
HashMap
记录类型数量,方便统计。
- 适用场景:
- 适用于需要根据特定规则计算类型数量的场景。
如果您有其他问题,欢迎随时提问!
四、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
中的前两个元素作为c
和b
。 - 提取剩余元素作为数组
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
进行处理,计算其类型。
- 对输入的整数
- 算法逻辑:
- 将整数
a
转换为十六进制字符串,并去除0x
前缀。 - 如果字符串长度为奇数,前面补零。
- 计算每两位的和
sumV
。 - 计算
sumV
模b
的余数t
。 - 如果
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())
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 算法逻辑:
- 使用字典
count
记录每种类型的数量。 - 遍历数组
arr
,对每个元素调用classify
函数,得到类型t
。 - 如果类型
t
不为-1
,记录该类型的数量。 - 返回
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
。
- 十六进制为
- 类型
1
和3
的数量均为1
,最大值为1
。
总结
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 优点:
- 使用十六进制转换和模运算快速计算类型。
- 使用字典记录类型数量,方便统计。
- 适用场景:
- 适用于需要根据特定规则计算类型数量的场景。
如果您有其他问题,欢迎随时提问!
五、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
动态存储输入数据。 - 提取前两个元素作为
c
和b
,剩余元素作为数组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
存储输入数据。 - 提取前两个元素作为
c
和b
,剩余元素作为数组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
。 - 计算
sumV
模b
的余数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));
总结
- 功能:
- 计算满足条件的类型数量,并返回最大值。
- 优点:
- 使用十六进制转换和模运算快速计算类型。
- 使用
map
(C++)或数组(C)记录类型数量,方便统计。
- 适用场景:
- 适用于需要根据特定规则计算类型数量的场景。
如果您有其他问题,欢迎随时提问!
六、尾言
什么是华为OD?
华为OD(Outsourcing Developer,外包开发工程师)是华为针对软件开发工程师岗位的一种招聘形式,主要包括笔试、技术面试以及综合面试等环节。尤其在笔试部分,算法题的机试至关重要。
为什么刷题很重要?
-
机试是进入技术面的第一关:
华为OD机试(常被称为机考)主要考察算法和编程能力。只有通过机试,才能进入后续的技术面试环节。 -
技术面试需要手撕代码:
技术一面和二面通常会涉及现场编写代码或算法题。面试官会注重考察候选人的思路清晰度、代码规范性以及解决问题的能力。因此提前刷题、多练习是通过面试的重要保障。 -
入职后的可信考试:
入职华为后,还需要通过“可信考试”。可信考试分为三个等级:- 入门级:主要考察基础算法与编程能力。
- 工作级:更贴近实际业务需求,可能涉及复杂的算法或与工作内容相关的场景题目。
- 专业级:最高等级,考察深层次的算法以及优化能力,与薪资直接挂钩。
刷题策略与说明:
2024年8月14日之后,华为OD机试的题库转为 E卷,由往年题库(D卷、A卷、B卷、C卷)和全新题目组成。刷题时可以参考以下策略:
-
关注历年真题:
- 题库中的旧题占比较大,建议优先刷历年的A卷、B卷、C卷、D卷题目。
- 对于每道题目,建议深度理解其解题思路、代码实现,以及相关算法的适用场景。
-
适应新题目:
- E卷中包含全新题目,需要掌握全面的算法知识和一定的灵活应对能力。
- 建议关注新的刷题平台或交流群,获取最新题目的解析和动态。
-
掌握常见算法:
华为OD考试通常涉及以下算法和数据结构:- 排序算法(快速排序、归并排序等)
- 动态规划(背包问题、最长公共子序列等)
- 贪心算法
- 栈、队列、链表的操作
- 图论(最短路径、最小生成树等)
- 滑动窗口、双指针算法
-
保持编程规范:
- 注重代码的可读性和注释的清晰度。
- 熟练使用常见编程语言,如C++、Java、Python等。
如何获取资源?
-
官方参考:
- 华为招聘官网或相关的招聘平台会有一些参考信息。
- 华为OD的相关公众号可能也会发布相关的刷题资料或学习资源。
-
加入刷题社区:
- 找到可信的刷题交流群,与其他备考的小伙伴交流经验。
- 关注知名的刷题网站,如LeetCode、牛客网等,这些平台上有许多华为OD的历年真题和解析。
-
寻找系统性的教程:
- 学习一本经典的算法书籍,例如《算法导论》《剑指Offer》《编程之美》等。
- 完成系统的学习课程,例如数据结构与算法的在线课程。
积极心态与持续努力:
刷题的过程可能会比较枯燥,但它能够显著提升编程能力和算法思维。无论是为了通过华为OD的招聘考试,还是为了未来的职业发展,这些积累都会成为重要的财富。
考试注意细节
-
本地编写代码
- 在本地 IDE(如 VS Code、PyCharm 等)上编写、保存和调试代码,确保逻辑正确后再复制粘贴到考试页面。这样可以减少语法错误,提高代码准确性。
-
调整心态,保持冷静
- 遇到提示不足或实现不确定的问题时,不必慌张,可以采用更简单或更有把握的方法替代,确保思路清晰。
-
输入输出完整性
- 注意训练和考试时都需要编写完整的输入输出代码,尤其是和题目示例保持一致。完成代码后务必及时调试,确保功能符合要求。
-
快捷键使用
- 删除行可用
Ctrl+D
,复制、粘贴和撤销分别为Ctrl+C
,Ctrl+V
,Ctrl+Z
,这些可以正常使用。 - 避免使用
Ctrl+S
,以免触发浏览器的保存功能。
- 删除行可用
-
浏览器要求
- 使用最新版的 Google Chrome 浏览器完成考试,确保摄像头开启并正常工作。考试期间不要切换到其他网站,以免影响考试成绩。
-
交卷相关
- 答题前,务必仔细查看题目示例,避免遗漏要求。
- 每完成一道题后,点击【保存并调试】按钮,多次保存和调试是允许的,系统会记录得分最高的一次结果。完成所有题目后,点击【提交本题型】按钮。
- 确保在考试结束前提交试卷,避免因未保存或调试失误而丢分。
-
时间和分数安排
- 总时间:150 分钟;总分:400 分。
- 试卷结构:2 道一星难度题(每题 100 分),1 道二星难度题(200 分)。及格分为 150 分。合理分配时间,优先完成自己擅长的题目。
-
考试环境准备
- 考试前请备好草稿纸和笔。考试中尽量避免离开座位,确保监控画面正常。
- 如需上厕所,请提前规划好时间以减少中途离开监控的可能性。
-
技术问题处理
- 如果考试中遇到断电、断网、死机等技术问题,可以关闭浏览器并重新打开试卷链接继续作答。
- 出现其他问题,请第一时间联系 HR 或监考人员进行反馈。
祝你考试顺利,取得理想成绩!