【2024年华为OD机试】 (C卷,100分)- 多段线数据压缩(JavaScriptJava PythonC/C++)

news2025/1/24 14:10:24

在这里插入图片描述

一、问题描述

问题描述

给定一个多线段的坐标列表,每个坐标由行号和列号表示。多线段的走向只能是水平、竖直或斜向45度。输入数据包含冗余的坐标点,要求输出最简化的坐标列表,仅保留起点、拐点和终点。

输入描述

  • 输入数据为多线段的坐标列表,每两个数字一组,分别表示行号和列号。
  • 所有数字以空格分隔。
  • 行号和列号范围为 [0, 64),输入数据保证不会越界。
  • 输入数据至少包含两个坐标点。

输出描述

  • 输出压缩后的最简化坐标列表,格式与输入相同。
  • 输出的坐标相对顺序不能变化。

示例

输入
2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5
输出
2 8 3 7 3 5 6 2 8 4 7 5

解题思路

1. 问题分析

本题的核心是识别多线段中的关键点(起点、拐点和终点),并去除冗余的中间点。关键点的特征是运动方向发生变化的点。

2. 运动方向的表示

  • 从点 A 到点 B 的运动方向可以用向量表示,即 (offsetX, offsetY),其中:
    • offsetX = B.x - A.x
    • offsetY = B.y - A.y
  • 为了简化方向比较,需要将向量归一化。归一化的方法是:
    • 计算 base = max(abs(offsetX), abs(offsetY))
    • 将向量 (offsetX, offsetY) 简化为 (offsetX / base, offsetY / base)

3. 拐点的判断

  • 对于连续三个点 A、B、C:
    • 计算 A→B 的方向向量 dir1
    • 计算 B→C 的方向向量 dir2
    • 如果 dir1dir2 不相同,则 B 是拐点。

4. 算法步骤

  1. 初始化
    • 将输入数据解析为坐标列表。
    • 将起点加入结果列表。
  2. 遍历坐标列表
    • 对于每个点,计算其与前一个点的方向向量。
    • 如果当前方向向量与前一个方向向量不同,则将前一个点加入结果列表。
  3. 结束
    • 将终点加入结果列表。
  4. 输出结果
    • 输出结果列表中的坐标。

关键点解析

1. 方向向量的归一化

  • 方向向量的归一化是为了统一表示相同方向的不同向量。例如:
    • 向量 (3, -3)(1, -1) 表示相同的方向。
    • 通过归一化,可以将 (3, -3) 简化为 (1, -1)

2. 拐点的判断

  • 拐点的判断基于运动方向的变化。如果当前方向与前一个方向不同,则当前点是拐点。
  • 例如:
    • A→B 的方向为 (1, -1),B→C 的方向为 (1, 0),则 B 是拐点。

3. 输出顺序

  • 输出的坐标顺序必须与输入顺序一致,不能改变。

示例解析

输入

2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

处理过程

  1. 起点(2, 8) 加入结果列表。
  2. 方向变化
    • (2, 8)(3, 7):方向为 (1, -1)
    • (3, 7)(3, 6):方向为 (0, -1),方向变化,(3, 7) 是拐点。
    • (3, 6)(3, 5):方向为 (0, -1),方向未变化。
    • (3, 5)(4, 4):方向为 (1, -1),方向变化,(3, 5) 是拐点。
    • (4, 4)(5, 3):方向为 (1, -1),方向未变化。
    • (5, 3)(6, 2):方向为 (1, -1),方向未变化。
    • (6, 2)(7, 3):方向为 (1, 1),方向变化,(6, 2) 是拐点。
    • (7, 3)(8, 4):方向为 (1, 1),方向未变化。
    • (8, 4)(7, 5):方向为 (-1, 1),方向变化,(8, 4) 是拐点。
  3. 终点(7, 5) 加入结果列表。

输出

2 8 3 7 3 5 6 2 8 4 7 5

总结

本题的核心是通过方向向量的变化识别拐点,并去除冗余的中间点。通过归一化方向向量,可以简化方向比较的逻辑。最终输出的坐标列表必须保持与输入相同的顺序。

二、JavaScript算法源码

这段代码实现了对多线段坐标列表的简化,仅保留起点、拐点和终点。以下是对代码的详细解析:


代码结构

  1. 输入处理

    • 使用 readline 模块读取输入,并将输入拆分为数字数组 nums
    • 调用 getResult 函数处理输入数据,并输出结果。
  2. 主函数 getResult

    • 初始化结果数组 ans,用于存储简化后的坐标。
    • 定义变量 preXpreY,表示上一个点的坐标。
    • 定义变量 preDirectXpreDirectY,表示上一次的运动方向。
    • 遍历输入坐标列表,计算当前点的运动方向,并与上一次的运动方向进行比较:
      • 如果方向不同,则上一个点是拐点,将其加入结果数组。
      • 更新 preXpreYpreDirectXpreDirectY
    • 遍历结束后,将最后一个点(终点)加入结果数组。
    • 返回结果数组,格式为空格分隔的字符串。

代码逻辑解析

1. 输入处理

  • 输入数据为多线段的坐标列表,每两个数字表示一个点的行号和列号。
  • 使用 split(" ") 将输入字符串拆分为数字数组 nums

2. 初始化

  • preXpreY 初始化为第一个点的坐标。
  • preDirectXpreDirectY 初始化为 0,表示初始方向未定义。

3. 遍历坐标列表

  • 从第二个点开始遍历,每次取两个数字作为当前点的坐标 (curX, curY)
  • 计算当前点与上一个点的偏移量 (offsetX, offsetY)
    • offsetX = curX - preX
    • offsetY = curY - preY
  • 根据偏移量计算当前运动方向 (directX, directY)
    • base = max(abs(offsetX), abs(offsetY))
    • directX = offsetX / base
    • directY = offsetY / base
  • 比较当前方向与上一次方向:
    • 如果方向不同,则上一个点是拐点,将其加入结果数组。
  • 更新 preXpreYpreDirectXpreDirectY

4. 收尾处理

  • 遍历结束后,将最后一个点(终点)加入结果数组。

5. 输出结果

  • 将结果数组转换为空格分隔的字符串并返回。

示例运行

输入

2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

处理过程

  1. 起点(2, 8)
  2. 方向变化
    • (2, 8)(3, 7):方向为 (1, -1)
    • (3, 7)(3, 6):方向为 (0, -1),方向变化,(3, 7) 是拐点。
    • (3, 6)(3, 5):方向为 (0, -1),方向未变化。
    • (3, 5)(4, 4):方向为 (1, -1),方向变化,(3, 5) 是拐点。
    • (4, 4)(5, 3):方向为 (1, -1),方向未变化。
    • (5, 3)(6, 2):方向为 (1, -1),方向未变化。
    • (6, 2)(7, 3):方向为 (1, 1),方向变化,(6, 2) 是拐点。
    • (7, 3)(8, 4):方向为 (1, 1),方向未变化。
    • (8, 4)(7, 5):方向为 (-1, 1),方向变化,(8, 4) 是拐点。
  3. 终点(7, 5)

输出

2 8 3 7 3 5 6 2 8 4 7 5

代码优化建议

  1. 变量命名

    • 可以将 preXpreY 合并为一个对象 prevPoint = { x, y },提高代码可读性。
    • 可以将 preDirectXpreDirectY 合并为一个对象 prevDirection = { x, y }
  2. 边界检查

    • 如果输入数据不足两个点,可以直接返回空数组或提示错误。
  3. 性能优化

    • 如果输入数据量较大,可以考虑使用更高效的数据结构或算法。

总结

这段代码通过遍历坐标列表,计算运动方向并识别拐点,最终输出了简化后的坐标列表。代码逻辑清晰,能够正确处理各种边界情况,适合学习和参考。

三、Java算法源码

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


代码结构

  1. 主函数 main

    • 使用 Scanner 读取输入,并将输入拆分为整数数组 nums
    • 调用 getResult 函数处理输入数据,并输出结果。
  2. 主逻辑函数 getResult

    • 使用 StringJoiner 存储简化后的坐标列表。
    • 定义变量 preXpreY,表示上一个点的坐标。
    • 定义变量 preDirectXpreDirectY,表示上一次的运动方向。
    • 遍历输入坐标列表,计算当前点的运动方向,并与上一次的运动方向进行比较:
      • 如果方向不同,则上一个点是拐点,将其加入结果列表。
      • 更新 preXpreYpreDirectXpreDirectY
    • 遍历结束后,将最后一个点(终点)加入结果列表。
    • 返回结果列表,格式为空格分隔的字符串。

代码逻辑解析

1. 输入处理

  • 使用 Scanner 读取输入,并通过 split(" ") 将输入字符串拆分为字符串数组。
  • 使用 Arrays.streammapToInt 将字符串数组转换为整数数组 nums

2. 初始化

  • 创建 StringJoiner 对象 sj,用于存储简化后的坐标列表。
  • preXpreY 初始化为第一个点的坐标。
  • preDirectXpreDirectY 初始化为 0,表示初始方向未定义。

3. 遍历坐标列表

  • 从第二个点开始遍历,每次取两个数字作为当前点的坐标 (curX, curY)
  • 计算当前点与上一个点的偏移量 (offsetX, offsetY)
    • offsetX = curX - preX
    • offsetY = curY - preY
  • 根据偏移量计算当前运动方向 (directX, directY)
    • base = max(abs(offsetX), abs(offsetY))
    • directX = offsetX / base
    • directY = offsetY / base
  • 比较当前方向与上一次方向:
    • 如果方向不同,则上一个点是拐点,将其加入结果列表。
  • 更新 preXpreYpreDirectXpreDirectY

4. 收尾处理

  • 遍历结束后,将最后一个点(终点)加入结果列表。

5. 输出结果

  • 使用 StringJoinertoString 方法将结果列表转换为空格分隔的字符串并返回。

代码详细注释

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

public class Main {
  public static void main(String[] args) {
    // 创建Scanner对象,用于读取输入
    Scanner sc = new Scanner(System.in);
    // 读取输入并拆分为整数数组
    int[] nums = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    // 调用getResult函数并输出结果
    System.out.println(getResult(nums));
  }

  public static String getResult(int[] nums) {
    // 创建StringJoiner对象,用于存储简化后的坐标列表
    StringJoiner sj = new StringJoiner(" ");

    // 上一个点坐标(preX, preY)
    int preX = nums[0];
    int preY = nums[1];

    // 上一次的运动方向(preDirectX, preDirectY)
    int preDirectX = 0;
    int preDirectY = 0;

    // 遍历坐标列表,从第二个点开始
    for (int i = 2; i < nums.length; i += 2) {
      // 当前点坐标(curX, curY)
      int curX = nums[i];
      int curY = nums[i + 1];

      // 上一个点到当前点的偏移量(offsetX, offsetY)
      int offsetX = curX - preX;
      int offsetY = curY - preY;

      // 根据偏移量得出本次的运动方向
      int base = Math.max(Math.abs(offsetX), Math.abs(offsetY));
      int directX = offsetX / base;
      int directY = offsetY / base;

      // 如果两次运动的方向不同
      if (directX != preDirectX || directY != preDirectY) {
        // 则上一个点是拐点,需要记录下来
        sj.add(preX + " " + preY);
      }

      // 更新上一个点的坐标和方向
      preX = curX;
      preY = curY;
      preDirectX = directX;
      preDirectY = directY;
    }

    // 注意收尾,将最后一个点(终点)加入结果列表
    sj.add(preX + " " + preY);

    // 返回结果列表
    return sj.toString();
  }
}

示例运行

输入

2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

处理过程

  1. 起点(2, 8)
  2. 方向变化
    • (2, 8)(3, 7):方向为 (1, -1)
    • (3, 7)(3, 6):方向为 (0, -1),方向变化,(3, 7) 是拐点。
    • (3, 6)(3, 5):方向为 (0, -1),方向未变化。
    • (3, 5)(4, 4):方向为 (1, -1),方向变化,(3, 5) 是拐点。
    • (4, 4)(5, 3):方向为 (1, -1),方向未变化。
    • (5, 3)(6, 2):方向为 (1, -1),方向未变化。
    • (6, 2)(7, 3):方向为 (1, 1),方向变化,(6, 2) 是拐点。
    • (7, 3)(8, 4):方向为 (1, 1),方向未变化。
    • (8, 4)(7, 5):方向为 (-1, 1),方向变化,(8, 4) 是拐点。
  3. 终点(7, 5)

输出

2 8 3 7 3 5 6 2 8 4 7 5

总结

这段代码通过遍历坐标列表,计算运动方向并识别拐点,最终输出了简化后的坐标列表。代码逻辑清晰,能够正确处理各种边界情况,适合学习和参考。

四、Python算法源码

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


代码结构

  1. 输入处理

    • 使用 input().split() 读取输入,并将输入拆分为整数列表 nums
  2. 主逻辑函数 getResult

    • 初始化结果列表 ans,用于存储简化后的坐标。
    • 定义变量 preXpreY,表示上一个点的坐标。
    • 定义变量 preDirectXpreDirectY,表示上一次的运动方向。
    • 遍历输入坐标列表,计算当前点的运动方向,并与上一次的运动方向进行比较:
      • 如果方向不同,则上一个点是拐点,将其加入结果列表。
      • 更新 preXpreYpreDirectXpreDirectY
    • 遍历结束后,将最后一个点(终点)加入结果列表。
    • 返回结果列表,格式为空格分隔的字符串。
  3. 算法调用

    • 调用 getResult 函数并输出结果。

代码逻辑解析

1. 输入处理

  • 使用 input().split() 将输入字符串拆分为字符串列表。
  • 使用 map(int, ...) 将字符串列表转换为整数列表 nums

2. 初始化

  • 创建空列表 ans,用于存储简化后的坐标。
  • preXpreY 初始化为第一个点的坐标。
  • preDirectXpreDirectY 初始化为 0,表示初始方向未定义。

3. 遍历坐标列表

  • 从第二个点开始遍历,每次取两个数字作为当前点的坐标 (curX, curY)
  • 计算当前点与上一个点的偏移量 (offsetX, offsetY)
    • offsetX = curX - preX
    • offsetY = curY - preY
  • 根据偏移量计算当前运动方向 (directX, directY)
    • base = max(abs(offsetX), abs(offsetY))
    • directX = offsetX // base
    • directY = offsetY // base
  • 比较当前方向与上一次方向:
    • 如果方向不同,则上一个点是拐点,将其加入结果列表。
  • 更新 preXpreYpreDirectXpreDirectY

4. 收尾处理

  • 遍历结束后,将最后一个点(终点)加入结果列表。

5. 输出结果

  • 使用 map(str, ans) 将结果列表中的整数转换为字符串。
  • 使用 " ".join(...) 将字符串列表拼接为空格分隔的字符串并返回。

代码详细注释

# 输入获取
nums = list(map(int, input().split()))

# 算法入口
def getResult():
    ans = []

    # 上一个点坐标(preX, preY)
    preX = nums[0]
    preY = nums[1]

    # 上一次的运动方向(preDirectX, preDirectY)
    preDirectX = 0
    preDirectY = 0

    # 遍历坐标列表,从第二个点开始
    for i in range(2, len(nums), 2):
        # 当前点坐标(curX, curY)
        curX = nums[i]
        curY = nums[i + 1]

        # 上一个点到当前点的偏移量(offsetX, offsetY)
        offsetX = curX - preX
        offsetY = curY - preY

        # 根据偏移量得出本次的运动方向
        base = max(abs(offsetX), abs(offsetY))
        directX = offsetX // base
        directY = offsetY // base

        # 如果两次运动的方向不同
        if directX != preDirectX or directY != preDirectY:
            # 则上一个点是拐点,需要记录下来
            ans.extend([preX, preY])

        # 更新上一个点的坐标和方向
        preX = curX
        preY = curY
        preDirectX = directX
        preDirectY = directY

    # 注意收尾,将最后一个点(终点)加入结果列表
    ans.extend([preX, preY])

    # 返回结果列表
    return " ".join(map(str, ans))

# 算法调用
print(getResult())

示例运行

输入

2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

处理过程

  1. 起点(2, 8)
  2. 方向变化
    • (2, 8)(3, 7):方向为 (1, -1)
    • (3, 7)(3, 6):方向为 (0, -1),方向变化,(3, 7) 是拐点。
    • (3, 6)(3, 5):方向为 (0, -1),方向未变化。
    • (3, 5)(4, 4):方向为 (1, -1),方向变化,(3, 5) 是拐点。
    • (4, 4)(5, 3):方向为 (1, -1),方向未变化。
    • (5, 3)(6, 2):方向为 (1, -1),方向未变化。
    • (6, 2)(7, 3):方向为 (1, 1),方向变化,(6, 2) 是拐点。
    • (7, 3)(8, 4):方向为 (1, 1),方向未变化。
    • (8, 4)(7, 5):方向为 (-1, 1),方向变化,(8, 4) 是拐点。
  3. 终点(7, 5)

输出

2 8 3 7 3 5 6 2 8 4 7 5

总结

这段代码通过遍历坐标列表,计算运动方向并识别拐点,最终输出了简化后的坐标列表。代码逻辑清晰,能够正确处理各种边界情况,适合学习和参考。

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

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


C++ 版本

#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

int main() {
    vector<int> nums; // 存储输入坐标的数组
    int num;

    // 读取输入,直到遇到换行符
    while (cin >> num) {
        nums.push_back(num);
        if (cin.get() != ' ') break; // 如果下一个字符不是空格,则结束输入
    }

    // 上一个点坐标(preX, preY)
    int preX = nums[0];
    int preY = nums[1];

    // 上一次的运动方向(preDirectX, preDirectY)
    int preDirectX = 0;
    int preDirectY = 0;

    // 遍历坐标列表,从第二个点开始
    for (int i = 2; i < nums.size(); i += 2) {
        // 当前点坐标(curX, curY)
        int curX = nums[i];
        int curY = nums[i + 1];

        // 上一个点到当前点的偏移量(offsetX, offsetY)
        int offsetX = curX - preX;
        int offsetY = curY - preY;

        // 根据偏移量得出本次的运动方向
        int base = max(abs(offsetX), abs(offsetY));
        int directX = offsetX / base;
        int directY = offsetY / base;

        // 如果两次运动的方向不同
        if (directX != preDirectX || directY != preDirectY) {
            // 则上一个点是拐点,需要记录下来
            cout << preX << " " << preY << " ";
        }

        // 更新上一个点的坐标和方向
        preX = curX;
        preY = curY;
        preDirectX = directX;
        preDirectY = directY;
    }

    // 注意收尾,将最后一个点(终点)输出
    cout << preX << " " << preY;

    return 0;
}

C语言版本

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

#define MAX_SIZE 20000 // 定义最大输入长度

int main() {
    int nums[MAX_SIZE]; // 存储输入坐标的数组
    int nums_size = 0;  // 输入坐标的数量

    // 读取输入,直到遇到换行符
    while (scanf("%d", &nums[nums_size++])) {
        if (getchar() != ' ') break; // 如果下一个字符不是空格,则结束输入
    }

    // 上一个点坐标(preX, preY)
    int preX = nums[0];
    int preY = nums[1];

    // 上一次的运动方向(preDirectX, preDirectY)
    int preDirectX = 0;
    int preDirectY = 0;

    // 遍历坐标列表,从第二个点开始
    for (int i = 2; i < nums_size; i += 2) {
        // 当前点坐标(curX, curY)
        int curX = nums[i];
        int curY = nums[i + 1];

        // 上一个点到当前点的偏移量(offsetX, offsetY)
        int offsetX = curX - preX;
        int offsetY = curY - preY;

        // 根据偏移量得出本次的运动方向
        int base = (int) fmax(abs(offsetX), abs(offsetY));
        int directX = offsetX / base;
        int directY = offsetY / base;

        // 如果两次运动的方向不同
        if (directX != preDirectX || directY != preDirectY) {
            // 则上一个点是拐点,需要记录下来
            printf("%d %d ", preX, preY);
        }

        // 更新上一个点的坐标和方向
        preX = curX;
        preY = curY;
        preDirectX = directX;
        preDirectY = directY;
    }

    // 注意收尾,将最后一个点(终点)输出
    printf("%d %d", preX, preY);

    return 0;
}

代码详细注释

1. 输入处理

  • C++
    • 使用 vector<int> 动态存储输入坐标。
    • 使用 cin 读取输入,直到遇到换行符。
  • C语言
    • 使用固定大小的数组 nums 存储输入坐标。
    • 使用 scanf 读取输入,直到遇到换行符。

2. 初始化

  • preXpreY 初始化为第一个点的坐标。
  • preDirectXpreDirectY 初始化为 0,表示初始方向未定义。

3. 遍历坐标列表

  • 从第二个点开始遍历,每次取两个数字作为当前点的坐标 (curX, curY)
  • 计算当前点与上一个点的偏移量 (offsetX, offsetY)
    • offsetX = curX - preX
    • offsetY = curY - preY
  • 根据偏移量计算当前运动方向 (directX, directY)
    • base = max(abs(offsetX), abs(offsetY))
    • directX = offsetX / base
    • directY = offsetY / base
  • 比较当前方向与上一次方向:
    • 如果方向不同,则上一个点是拐点,将其输出。

4. 收尾处理

  • 遍历结束后,将最后一个点(终点)输出。

示例运行

输入

2 8 3 7 3 6 3 5 4 4 5 3 6 2 7 3 8 4 7 5

处理过程

  1. 起点(2, 8)
  2. 方向变化
    • (2, 8)(3, 7):方向为 (1, -1)
    • (3, 7)(3, 6):方向为 (0, -1),方向变化,(3, 7) 是拐点。
    • (3, 6)(3, 5):方向为 (0, -1),方向未变化。
    • (3, 5)(4, 4):方向为 (1, -1),方向变化,(3, 5) 是拐点。
    • (4, 4)(5, 3):方向为 (1, -1),方向未变化。
    • (5, 3)(6, 2):方向为 (1, -1),方向未变化。
    • (6, 2)(7, 3):方向为 (1, 1),方向变化,(6, 2) 是拐点。
    • (7, 3)(8, 4):方向为 (1, 1),方向未变化。
    • (8, 4)(7, 5):方向为 (-1, 1),方向变化,(8, 4) 是拐点。
  3. 终点(7, 5)

输出

2 8 3 7 3 5 6 2 8 4 7 5

总结

这段代码通过遍历坐标列表,计算运动方向并识别拐点,最终输出了简化后的坐标列表。代码逻辑清晰,能够正确处理各种边界情况,适合学习和参考。

六、尾言

什么是华为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.coloradmin.cn/o/2281454.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

状态模式——C++实现

目录 1. 状态模式简介 2. 代码示例 3. 单例状态对象 4. 状态模式与策略模式的辨析 1. 状态模式简介 状态模式是一种行为型模式。 状态模式的定义&#xff1a;状态模式允许对象在内部状态改变时改变它的行为&#xff0c;对象看起来好像修改了它的类。 通俗的说就是一个对象…

数据库SQLite和SCADA DIAView应用教程

课程简介 此系列课程大纲主要包含七个课时。主要使用到的开发工具有&#xff1a;SQLite studio 和 SCADA DIAView。详细的可成内容大概如下&#xff1a; 1、SQLite 可视化管理工具SQLite Studio &#xff1a;打开数据库和查询数据&#xff1b;查看视频 2、创建6个变量&#x…

java开发,IDEA转战VSCODE配置(mac)

一、基本java开发环境配置 前提&#xff1a;已经安装了jdk、maven、vscode&#xff0c;且配置了环境变量 1、安装java相关的插件 2、安装spring相关的插件 3、vscode配置maven环境 打开 VsCode -> 首选项 -> 设置&#xff0c;也可以在setting.json文件中直接编辑&…

python爬虫的学习流程(1-前提准备)

这里主要记录一下我的python爬虫初级的学习的流程 1.python爬虫入门实战课 什么是爬虫&#xff1f;众说纷纭&#xff0c;我们引用维基百科上对网络爬虫的介绍&#xff1a; 网络爬虫&#xff08;英语&#xff1a;Web crawler&#xff09;&#xff0c;也叫网络蜘蛛&#xff08;…

数据结构初阶之双向链表的介绍与双向链表的实现

一、概念与结构 带头双向循环链表 next &#xff1a;指向下一个结点&#xff08;后继结点&#xff09; prev &#xff1a;指向前一个结点&#xff08;前驱结点&#xff09; 二、实现双向链表 项目创建的时候&#xff0c;要创建一个头文件&#xff08;.h&#xff09;List.h …

CICD集合(六):Jenkins配置Editable Email Notification

CICD集合(六):Jenkins配置Editable Email Notification 1、系统配置 1.1、Jenkins Location 1.2、邮件通知 1、SMTP服务器:imap.exmail.qq.com (因qq企业邮箱) 2、邮箱后缀:@xxx.com 3、勾选:使用SMTP认证 用户名:

Golang 中除了加锁还有哪些安全读写共享变量的方式?

Golang 中除了加锁还有哪些安全读写共享变量的方式&#xff1f; 在 Golang 中&#xff0c;除了使用 Mutex 锁来保护共享变量外&#xff0c;还可以通过 Channel 和 原子性操作 来实现安全读写共享变量。 1. 使用 Channel 原理 Channel 是 Golang 中用于 Goroutine 之间通信的…

应用层协议 HTTP 讲解实战:从0实现HTTP 服务器

&#x1f308; 个人主页&#xff1a;Zfox_ &#x1f525; 系列专栏&#xff1a;Linux 目录 一&#xff1a;&#x1f525; HTTP 协议 &#x1f98b; 认识 URL&#x1f98b; urlencode 和 urldecode 二&#xff1a;&#x1f525; HTTP 协议请求与响应格式 &#x1f98b; HTTP 请求…

F/V/F/I频率脉冲信号转换器

F/V/F/I频率脉冲信号转换器 概述&#xff1a;捷晟达科技的JSD TFA-1001系列是一进一出频率脉冲信号转换器(F/V转换器),该频率转换器是将频率脉冲信号(方波、正弦波、锯齿波)转换成国际标准的模拟量电压(电流)信号,并远距离无失真传送到控制室(如:PLC,DCS,AD,PC采集系统)产品的输…

Windows的docker中安装gitlab

一.Windows的docker中安装gitlab 1.通过阿里云拉取镜像 docker pull registry.cn-hangzhou.aliyuncs.com/lab99/gitlab-ce-zh 2.在本地创建备份数据的目录 mkdir -p D:home/software/gitlab/etc mkdir -p D:home/software/gitlab/logs mkdir -p D:home/software/gitlab/dat…

【Linux】理解Linux中一切皆文件、缓冲区、ext2文件系统、软硬链接

⭐️个人主页&#xff1a;小羊 ⭐️所属专栏&#xff1a;Linux 很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~ 目录 1、如何理解在Linux中一切皆文件&#xff1f;1.1 概述1.2 文件类型1.3 优势 2、缓冲区2.1 为什么要引入缓冲区&#xff1f;2.2 缓…

在Docker 容器中安装 Oracle 19c

在 Docker 容器中安装 Oracle 19c 是可行的&#xff0c;但它相较于其他数据库&#xff08;如 MySQL、PostgreSQL 等&#xff09;会复杂一些&#xff0c;因为 Oracle 数据库有一些特定的要求&#xff0c;如操作系统和库的依赖&#xff0c;以及许可证问题。 不过&#xff0c;Ora…

【数据库】详解MySQL数据库中的事务与锁

目录 1.数据库事务 1.1.事务的四大特性 1.2.事务开启的方式 1.3.读一致性问题及其解决 2.MVCC解决读一致性问题原理 2.1.MVCC概念 2.2.准备环境 3.MySQL中的锁 3.1.行锁之共享锁 3.2.行锁之排它锁 1.数据库事务 数据库事务&#xff08;Transaction&#xff09;是一种…

springboot 配置redis

环境配置 springboot3.4 redis5.0.14 redis准备参考下面文章 window下安装redis以及启动 redis客户端安装 引入依赖 <!-- 集成redis依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-…

EEG代码实践:diffusion EEG——扩散模型生成EEG信号

2024/1/22&#xff1a; 原始EEG信号的生成说实话一直做不到让人满意的水平&#xff0c;之前做的MIEEG复现也迟迟没有调整到自己想要的程度&#xff0c;与论文中的效果还是有些差距。改换思路使用离散小波变换&#xff0c;用变换之后的信号做生成任务则好了许多。从大二开始一直…

Banana Pi BPI-RV2 开发板矽昌通信 RISC-V路由芯片SF21H8898优势亮点

Banana Pi BPI-RV3开源路由器 1. 8898芯片具备强大的网络加速硬件性能&#xff0c;能够在小字节报文条件下实现高效数据转发&#xff1a;  单WAN口性能&#xff1a;支持 64 字节报文单向转发速率达到 2.5 Gbps&#xff0c;双向转发速率为 5 Gbps。双WAN口性能&#xff1a;支…

光谱相机在智能冰箱的应用原理与优势

食品新鲜度检测 详细可点击查看汇能感知团队实验报告&#xff1a;高光谱成像技术检测食物新鲜度 检测原理&#xff1a;不同新鲜程度的食品&#xff0c;其化学成分和结构会有所不同&#xff0c;在光谱下的反射、吸收等特性也存在差异。例如新鲜肉类和蔬菜中的水分、蛋白质、叶…

xxljob执行失败,xxl-job remoting error(sl.nts.com), for url : http://xxxxxxxxxx/run

问题 项目部署后&#xff0c;发现xxljob没有正常工作&#xff0c;报错 尝试解决&#xff1a; &#xff08;1&#xff09;检查xxljob配置&#xff08;无问题&#xff09; &#xff08;2&#xff09;检查服务器hosts文件域名配置&#xff08;依旧无问题&#xff09; 各种能检查…

什么是全息展示

全息展示。这一术语来源于“全息图”&#xff08;Holography&#xff09;的概念&#xff0c;而“全息图”这个词是由希腊词根 "holos" 演变而来&#xff0c;意为“整体的”或“完整的”。全息技术的核心在于它能够捕捉并再现物体的所有光学信息——不仅仅是强度&…

服务器内部是如何运行的

服务器内部的运行可以从硬件和软件两个方面来解释。 一、硬件层面 服务器的硬件与普通计算机相似,但它通常具有更高的性能和更强的扩展性。服务器硬件包括: 1.中央处理单元(CPU):负责执行服务器上的计算任务。服务器一般配备多核心的高性能CPU,以支持多个请求并行处理…