自学内容网 自学内容网

【2024年华为OD机试】 (A卷,200分)- 不含101的数(Java & JS & Python&C/C++)

在这里插入图片描述

一、问题描述

题目描述

小明在学习二进制时,发现了一类不含 101的数,也就是:

将数字用二进制表示,不能出现 101 。
现在给定一个整数区间 [l,r] ,请问这个区间包含了多少个不含 101 的数?

输入描述

输入的唯一一行包含两个正整数 l, r( 1 ≤ l ≤ r ≤ 10^9)。

输出描述

输出的唯一一行包含一个整数,表示在 [l,r] 区间内一共有几个不含 101 的数。

用例

用例1

输入

1 10

输出

8

说明
区间 [1,10] 内, 5 的二进制表示为 101 ,10的二进制表示为

二、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) => {
  // 将输入行按空格分割,并转换为数字
  const [L, R] = line.split(" ").map(Number);

  // 计算 [L, R] 范围内满足条件的数字个数
  const count = digitSearch(R) - digitSearch(L - 1);

  // 输出结果
  console.log(count);
});

// 核心函数:计算小于等于 num 的满足条件的数字个数
function digitSearch(num) {
  // 将数字 num 转换为二进制字符串,并拆分为数字数组
  const arr = num.toString(2).split("").map(Number);

  // 初始化记忆化数组 f,用于存储中间结果
  const f = new Array(arr.length)
    .fill(0)
    .map(() => new Array(2).fill(0).map(() => new Array(2)));

  // 调用深度优先搜索函数 dfs
  return dfs(0, true, f, arr, 0, 0);
}

// 深度优先搜索函数
function dfs(p, limit, f, arr, pre, prepre) {
  // 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)
  if (p === arr.length) return 1;

  // 如果当前状态已经计算过,直接返回结果(记忆化)
  if (!limit && f[p][pre][prepre]) return f[p][pre][prepre];

  // 当前位的最大值(如果有限制,则为 arr[p],否则为 1)
  const max = limit ? arr[p] : 1;
  let count = 0;

  // 遍历当前位的所有可能值(0 或 1)
  for (let i = 0; i <= max; i++) {
    // 如果当前位是 1,且前两位是 0 和 1,则跳过(避免出现 "101" 模式)
    if (i === 1 && pre === 0 && prepre === 1) continue;

    // 递归计算下一位的结果,并累加到 count
    count += dfs(p + 1, limit && i === max, f, arr, i, pre);
  }

  // 如果没有限制,将当前状态的结果存入记忆化数组
  if (!limit) f[p][pre][prepre] = count;

  // 返回当前状态的结果
  return count;
}

详细讲解


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

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

rl.on("line", (line) => {
  const [L, R] = line.split(" ").map(Number);
  const count = digitSearch(R) - digitSearch(L - 1);
  console.log(count);
});
  • 功能:
    • 使用 readline 模块从控制台读取输入。
    • 将输入行按空格分割,并转换为数字 LR
    • 计算 [L, R] 范围内满足条件的数字个数,并输出结果。

2. 核心函数 digitSearch
function digitSearch(num) {
  const arr = num.toString(2).split("").map(Number);
  const f = new Array(arr.length)
    .fill(0)
    .map(() => new Array(2).fill(0).map(() => new Array(2)));

  return dfs(0, true, f, arr, 0, 0);
}
  • 功能:
    • 计算小于等于 num 的满足条件的数字个数。
  • 逻辑:
    1. 将数字 num 转换为二进制字符串,并拆分为数字数组 arr
    2. 初始化记忆化数组 f,用于存储中间结果。
    3. 调用深度优先搜索函数 dfs,从第 0 位开始搜索。

3. 深度优先搜索函数 dfs
function dfs(p, limit, f, arr, pre, prepre) {
  if (p === arr.length) return 1;

  if (!limit && f[p][pre][prepre]) return f[p][pre][prepre];

  const max = limit ? arr[p] : 1;
  let count = 0;

  for (let i = 0; i <= max; i++) {
    if (i === 1 && pre === 0 && prepre === 1) continue;
    count += dfs(p + 1, limit && i === max, f, arr, i, pre);
  }

  if (!limit) f[p][pre][prepre] = count;

  return count;
}
  • 功能:
    • 递归搜索满足条件的数字个数。
  • 参数:
    • p:当前处理的位数。
    • limit:是否受到当前位的限制。
    • f:记忆化数组,用于存储中间结果。
    • arr:二进制数字数组。
    • pre:前一位的值。
    • prepre:前两位的值。
  • 逻辑:
    1. 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)。
    2. 如果当前状态已经计算过,直接返回结果(记忆化)。
    3. 遍历当前位的所有可能值(0 或 1),并递归计算下一位的结果。
    4. 如果没有限制,将当前状态的结果存入记忆化数组。
    5. 返回当前状态的结果。

代码运行示例

示例 1:

输入:

1 10

输出:

8

解释:

  • [1, 10] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 1(1)
    • 2(10)
    • 3(11)
    • 4(100)
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
  • 满足条件的数字个数为 8

示例 2:

输入:

5 15

输出:

7

解释:

  • [5, 15] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
    • 11(1011)→ 不满足条件
    • 12(1100)
    • 13(1101)→ 不满足条件
    • 14(1110)
    • 15(1111)
  • 满足条件的数字个数为 7

总结

  1. 功能:
    • 计算 [L, R] 范围内二进制表示中不包含 “101” 模式的数字个数。
  2. 优点:
    • 使用深度优先搜索(DFS)和记忆化技术,避免重复计算。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:
    • 适用于需要统计二进制表示中不包含特定模式的数字个数的场景。

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

三、Java算法源码

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


Java 代码

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

public class Main {
  public static void main(String[] args) {
    // 创建 Scanner 对象,用于从控制台读取输入
    Scanner sc = new Scanner(System.in);

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

    // 计算 [L, R] 范围内满足条件的数字个数
    int count = digitSearch(R) - digitSearch(L - 1);

    // 输出结果
    System.out.println(count);
  }

  // 核心函数:计算小于等于 num 的满足条件的数字个数
  public static int digitSearch(int num) {
    // 将数字 num 转换为二进制字符串,并拆分为 Integer 数组
    Integer[] arr =
        Arrays.stream(Integer.toBinaryString(num).split(""))
            .map(Integer::parseInt)
            .toArray(Integer[]::new);

    // 初始化记忆化数组 f,用于存储中间结果
    int[][][] f = new int[arr.length][2][2];

    // 调用深度优先搜索函数 dfs
    return dfs(0, true, f, arr, 0, 0);
  }

  // 深度优先搜索函数
  public static int dfs(int p, boolean limit, int[][][] f, Integer[] arr, int pre, int prepre) {
    // 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)
    if (p == arr.length) return 1;

    // 如果当前状态已经计算过,直接返回结果(记忆化)
    if (!limit && f[p][pre][prepre] != 0) return f[p][pre][prepre];

    // 当前位的最大值(如果有限制,则为 arr[p],否则为 1)
    int max = limit ? arr[p] : 1;
    int count = 0;

    // 遍历当前位的所有可能值(0 或 1)
    for (int i = 0; i <= max; i++) {
      // 如果当前位是 1,且前两位是 0 和 1,则跳过(避免出现 "101" 模式)
      if (i == 1 && pre == 0 && prepre == 1) continue;

      // 递归计算下一位的结果,并累加到 count
      count += dfs(p + 1, limit && i == max, f, arr, i, pre);
    }

    // 如果没有限制,将当前状态的结果存入记忆化数组
    if (!limit) f[p][pre][prepre] = count;

    // 返回当前状态的结果
    return count;
  }
}

详细讲解


1. 输入处理
Scanner sc = new Scanner(System.in);
int L = sc.nextInt();
int R = sc.nextInt();
int count = digitSearch(R) - digitSearch(L - 1);
System.out.println(count);
  • 功能:
    • 使用 Scanner 从控制台读取输入的两个整数 LR
    • 计算 [L, R] 范围内满足条件的数字个数,并输出结果。

2. 核心函数 digitSearch
public static int digitSearch(int num) {
  Integer[] arr =
      Arrays.stream(Integer.toBinaryString(num).split(""))
          .map(Integer::parseInt)
          .toArray(Integer[]::new);

  int[][][] f = new int[arr.length][2][2];

  return dfs(0, true, f, arr, 0, 0);
}
  • 功能:
    • 计算小于等于 num 的满足条件的数字个数。
  • 逻辑:
    1. 将数字 num 转换为二进制字符串,并拆分为 Integer 数组 arr
    2. 初始化记忆化数组 f,用于存储中间结果。
    3. 调用深度优先搜索函数 dfs,从第 0 位开始搜索。

3. 深度优先搜索函数 dfs
public static int dfs(int p, boolean limit, int[][][] f, Integer[] arr, int pre, int prepre) {
  if (p == arr.length) return 1;

  if (!limit && f[p][pre][prepre] != 0) return f[p][pre][prepre];

  int max = limit ? arr[p] : 1;
  int count = 0;

  for (int i = 0; i <= max; i++) {
    if (i == 1 && pre == 0 && prepre == 1) continue;
    count += dfs(p + 1, limit && i == max, f, arr, i, pre);
  }

  if (!limit) f[p][pre][prepre] = count;

  return count;
}
  • 功能:
    • 递归搜索满足条件的数字个数。
  • 参数:
    • p:当前处理的位数。
    • limit:是否受到当前位的限制。
    • f:记忆化数组,用于存储中间结果。
    • arr:二进制数字数组。
    • pre:前一位的值。
    • prepre:前两位的值。
  • 逻辑:
    1. 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)。
    2. 如果当前状态已经计算过,直接返回结果(记忆化)。
    3. 遍历当前位的所有可能值(0 或 1),并递归计算下一位的结果。
    4. 如果没有限制,将当前状态的结果存入记忆化数组。
    5. 返回当前状态的结果。

代码运行示例

示例 1:

输入:

1 10

输出:

8

解释:

  • [1, 10] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 1(1)
    • 2(10)
    • 3(11)
    • 4(100)
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
  • 满足条件的数字个数为 8

示例 2:

输入:

5 15

输出:

7

解释:

  • [5, 15] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
    • 11(1011)→ 不满足条件
    • 12(1100)
    • 13(1101)→ 不满足条件
    • 14(1110)
    • 15(1111)
  • 满足条件的数字个数为 7

总结

  1. 功能:
    • 计算 [L, R] 范围内二进制表示中不包含 “101” 模式的数字个数。
  2. 优点:
    • 使用深度优先搜索(DFS)和记忆化技术,避免重复计算。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:
    • 适用于需要统计二进制表示中不包含特定模式的数字个数的场景。

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

四、Python算法源码

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


Python 代码

# 深度优先搜索函数
def dfs(p, limit, f, arr, pre, prepre):
    # 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)
    if p == len(arr):
        return 1

    # 如果当前状态已经计算过,直接返回结果(记忆化)
    if not limit and f[p][pre][prepre] > 0:
        return f[p][pre][prepre]

    # 当前位的最大值(如果有限制,则为 arr[p],否则为 1)
    maxV = arr[p] if limit else 1
    count = 0

    # 遍历当前位的所有可能值(0 或 1)
    for i in range(maxV + 1):
        # 如果当前位是 1,且前两位是 0 和 1,则跳过(避免出现 "101" 模式)
        if i == 1 and pre == 0 and prepre == 1:
            continue

        # 递归计算下一位的结果,并累加到 count
        count += dfs(p + 1, limit and i == maxV, f, arr, i, pre)

    # 如果没有限制,将当前状态的结果存入记忆化数组
    if not limit:
        f[p][pre][prepre] = count

    # 返回当前状态的结果
    return count


# 核心函数:计算小于等于 num 的满足条件的数字个数
def digitSearch(num):
    # 将数字 num 转换为二进制字符串,并拆分为数字列表
    arr = list(map(int, list(format(num, 'b'))))

    # 初始化记忆化数组 f,用于存储中间结果
    f = [[[0 for k in range(2)] for j in range(2)] for i in range(len(arr))]

    # 调用深度优先搜索函数 dfs
    return dfs(0, True, f, arr, 0, 0)


# 输入获取
L, R = map(int, input().split())

# 算法调用
print(digitSearch(R) - digitSearch(L - 1))

详细讲解


1. 深度优先搜索函数 dfs
def dfs(p, limit, f, arr, pre, prepre):
    if p == len(arr):
        return 1

    if not limit and f[p][pre][prepre] > 0:
        return f[p][pre][prepre]

    maxV = arr[p] if limit else 1
    count = 0

    for i in range(maxV + 1):
        if i == 1 and pre == 0 and prepre == 1:
            continue
        count += dfs(p + 1, limit and i == maxV, f, arr, i, pre)

    if not limit:
        f[p][pre][prepre] = count

    return count
  • 功能:
    • 递归搜索满足条件的数字个数。
  • 参数:
    • p:当前处理的位数。
    • limit:是否受到当前位的限制。
    • f:记忆化数组,用于存储中间结果。
    • arr:二进制数字列表。
    • pre:前一位的值。
    • prepre:前两位的值。
  • 逻辑:
    1. 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)。
    2. 如果当前状态已经计算过,直接返回结果(记忆化)。
    3. 遍历当前位的所有可能值(0 或 1),并递归计算下一位的结果。
    4. 如果没有限制,将当前状态的结果存入记忆化数组。
    5. 返回当前状态的结果。

2. 核心函数 digitSearch
def digitSearch(num):
    arr = list(map(int, list(format(num, 'b'))))
    f = [[[0 for k in range(2)] for j in range(2)] for i in range(len(arr))]
    return dfs(0, True, f, arr, 0, 0)
  • 功能:
    • 计算小于等于 num 的满足条件的数字个数。
  • 逻辑:
    1. 将数字 num 转换为二进制字符串,并拆分为数字列表 arr
    2. 初始化记忆化数组 f,用于存储中间结果。
    3. 调用深度优先搜索函数 dfs,从第 0 位开始搜索。

3. 输入处理与算法调用
L, R = map(int, input().split())
print(digitSearch(R) - digitSearch(L - 1))
  • 功能:
    • 从控制台读取输入的两个整数 LR
    • 计算 [L, R] 范围内满足条件的数字个数,并输出结果。

代码运行示例

示例 1:

输入:

1 10

输出:

8

解释:

  • [1, 10] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 1(1)
    • 2(10)
    • 3(11)
    • 4(100)
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
  • 满足条件的数字个数为 8

示例 2:

输入:

5 15

输出:

7

解释:

  • [5, 15] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
    • 11(1011)→ 不满足条件
    • 12(1100)
    • 13(1101)→ 不满足条件
    • 14(1110)
    • 15(1111)
  • 满足条件的数字个数为 7

总结

  1. 功能:
    • 计算 [L, R] 范围内二进制表示中不包含 “101” 模式的数字个数。
  2. 优点:
    • 使用深度优先搜索(DFS)和记忆化技术,避免重复计算。
    • 代码逻辑清晰,易于理解。
  3. 适用场景:
    • 适用于需要统计二进制表示中不包含特定模式的数字个数的场景。

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

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

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


C++ 代码

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// 深度优先搜索函数
int dfs(int p, bool limit, vector<vector<vector<int>>>& f, const vector<int>& arr, int pre, int prepre) {
    // 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)
    if (p == arr.size()) return 1;

    // 如果当前状态已经计算过,直接返回结果(记忆化)
    if (!limit && f[p][pre][prepre] > 0) return f[p][pre][prepre];

    // 当前位的最大值(如果有限制,则为 arr[p],否则为 1)
    int maxV = limit ? arr[p] : 1;
    int count = 0;

    // 遍历当前位的所有可能值(0 或 1)
    for (int i = 0; i <= maxV; i++) {
        // 如果当前位是 1,且前两位是 0 和 1,则跳过(避免出现 "101" 模式)
        if (i == 1 && pre == 0 && prepre == 1) continue;

        // 递归计算下一位的结果,并累加到 count
        count += dfs(p + 1, limit && i == maxV, f, arr, i, pre);
    }

    // 如果没有限制,将当前状态的结果存入记忆化数组
    if (!limit) f[p][pre][prepre] = count;

    // 返回当前状态的结果
    return count;
}

// 核心函数:计算小于等于 num 的满足条件的数字个数
int digitSearch(int num) {
    // 将数字 num 转换为二进制字符串,并拆分为数字数组
    string binary = "";
    while (num > 0) {
        binary = to_string(num % 2) + binary;
        num /= 2;
    }
    vector<int> arr;
    for (char c : binary) {
        arr.push_back(c - '0');
    }

    // 初始化记忆化数组 f,用于存储中间结果
    vector<vector<vector<int>>> f(arr.size(), vector<vector<int>>(2, vector<int>(2, 0)));

    // 调用深度优先搜索函数 dfs
    return dfs(0, true, f, arr, 0, 0);
}

int main() {
    // 输入获取
    int L, R;
    cin >> L >> R;

    // 算法调用
    cout << digitSearch(R) - digitSearch(L - 1) << endl;

    return 0;
}

C 语言代码

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

// 深度优先搜索函数
int dfs(int p, int limit, int f[][2][2], int* arr, int arrSize, int pre, int prepre) {
    // 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)
    if (p == arrSize) return 1;

    // 如果当前状态已经计算过,直接返回结果(记忆化)
    if (!limit && f[p][pre][prepre] > 0) return f[p][pre][prepre];

    // 当前位的最大值(如果有限制,则为 arr[p],否则为 1)
    int maxV = limit ? arr[p] : 1;
    int count = 0;

    // 遍历当前位的所有可能值(0 或 1)
    for (int i = 0; i <= maxV; i++) {
        // 如果当前位是 1,且前两位是 0 和 1,则跳过(避免出现 "101" 模式)
        if (i == 1 && pre == 0 && prepre == 1) continue;

        // 递归计算下一位的结果,并累加到 count
        count += dfs(p + 1, limit && i == maxV, f, arr, arrSize, i, pre);
    }

    // 如果没有限制,将当前状态的结果存入记忆化数组
    if (!limit) f[p][pre][prepre] = count;

    // 返回当前状态的结果
    return count;
}

// 核心函数:计算小于等于 num 的满足条件的数字个数
int digitSearch(int num) {
    // 将数字 num 转换为二进制字符串,并拆分为数字数组
    char binary[32];
    int index = 0;
    while (num > 0) {
        binary[index++] = (num % 2) + '0';
        num /= 2;
    }
    binary[index] = '\0';

    // 反转二进制字符串
    for (int i = 0; i < index / 2; i++) {
        char temp = binary[i];
        binary[i] = binary[index - 1 - i];
        binary[index - 1 - i] = temp;
    }

    int arrSize = strlen(binary);
    int* arr = (int*)malloc(arrSize * sizeof(int));
    for (int i = 0; i < arrSize; i++) {
        arr[i] = binary[i] - '0';
    }

    // 初始化记忆化数组 f,用于存储中间结果
    int f[arrSize][2][2];
    memset(f, 0, sizeof(f));

    // 调用深度优先搜索函数 dfs
    int result = dfs(0, 1, f, arr, arrSize, 0, 0);

    // 释放动态分配的内存
    free(arr);

    return result;
}

int main() {
    // 输入获取
    int L, R;
    scanf("%d %d", &L, &R);

    // 算法调用
    printf("%d\n", digitSearch(R) - digitSearch(L - 1));

    return 0;
}

详细讲解


1. 深度优先搜索函数 dfs
  • 功能:
    • 递归搜索满足条件的数字个数。
  • 参数:
    • p:当前处理的位数。
    • limit:是否受到当前位的限制。
    • f:记忆化数组,用于存储中间结果。
    • arr:二进制数字数组。
    • pre:前一位的值。
    • prepre:前两位的值。
  • 逻辑:
    1. 如果已经遍历完所有位数,返回 1(表示找到一个符合条件的数字)。
    2. 如果当前状态已经计算过,直接返回结果(记忆化)。
    3. 遍历当前位的所有可能值(0 或 1),并递归计算下一位的结果。
    4. 如果没有限制,将当前状态的结果存入记忆化数组。
    5. 返回当前状态的结果。

2. 核心函数 digitSearch
  • 功能:
    • 计算小于等于 num 的满足条件的数字个数。
  • 逻辑:
    1. 将数字 num 转换为二进制字符串,并拆分为数字数组。
    2. 初始化记忆化数组 f,用于存储中间结果。
    3. 调用深度优先搜索函数 dfs,从第 0 位开始搜索。

3. 输入处理与算法调用
  • 功能:
    • 从控制台读取输入的两个整数 LR
    • 计算 [L, R] 范围内满足条件的数字个数,并输出结果。

代码运行示例

示例 1:

输入:

1 10

输出:

8

解释:

  • [1, 10] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 1(1)
    • 2(10)
    • 3(11)
    • 4(100)
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
  • 满足条件的数字个数为 8

示例 2:

输入:

5 15

输出:

7

解释:

  • [5, 15] 范围内,二进制表示中不包含 “101” 模式的数字有:
    • 5(101)→ 不满足条件
    • 6(110)
    • 7(111)
    • 8(1000)
    • 9(1001)
    • 10(1010)→ 不满足条件
    • 11(1011)→ 不满足条件
    • 12(1100)
    • 13(1101)→ 不满足条件
    • 14(1110)
    • 15(1111)
  • 满足条件的数字个数为 7

总结

  1. 功能:
    • 计算 [L, R] 范围内二进制表示中不包含 “101” 模式的数字个数。
  2. 优点:
    • 使用深度优先搜索(DFS)和记忆化技术,避免重复计算。
    • 代码逻辑清晰,易于理解。
  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 或监考人员进行反馈。

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


原文地址:https://blog.csdn.net/m0_63168877/article/details/145158969

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!