【2024年华为OD机试】 (C卷,200分)- 矩阵匹配(JavaScriptJava PythonC/C++)

一、问题描述
问题描述
给定一个大小为 ( N \times M )(( N \leq M ))的矩阵,从中选出 ( N ) 个数,要求任意两个数字不能在同一行或同一列。求选出来的 ( N ) 个数中第 ( K ) 大的数字的最小值。
输入描述
- 输入矩阵要求:( 1 \leq K \leq N \leq M \leq 150 )
- 输入格式:
- 第一行:( N ) ( M ) ( K )
- 接下来 ( N ) 行:( N \times M ) 矩阵
输出描述
- 输出从矩阵中选出的 ( N ) 个数中第 ( K ) 大的数字的最小值。
用例
输入
3 4 2
1 5 6 6
8 3 4 3
6 8 6 3
输出
3
解题思路
1. 问题分析
我们需要从矩阵中选出 ( N ) 个数,且这些数不能在同一行或同一列。然后在这些选出的数中找到第 ( K ) 大的数的最小值。
2. 二分图匹配
- 将矩阵的行和列分别看作二分图的两部分。
- 选择 ( N ) 个数且不重复行和列,相当于在二分图中找到一个匹配,匹配的边数至少为 ( N )。
- 我们需要找到这些匹配中第 ( K ) 大的数的最小值。
3. 二分法
- 使用二分法来枚举可能的第 ( K ) 大的数 ( kth )。
- 对于每个枚举的 ( kth ),检查矩阵中是否有至少 ( N - K + 1 ) 个数小于等于 ( kth ),并且这些数不在同一行或同一列。
- 如果满足条件,则尝试更小的 ( kth );否则,尝试更大的 ( kth )。
4. 二分图最大匹配
- 对于每个 ( kth ),构建一个新的二分图,其中只包含矩阵中值小于等于 ( kth ) 的元素。
- 在这个新的二分图中,寻找最大匹配。如果最大匹配数大于等于 ( N - K + 1 ),则说明 ( kth ) 可能是一个候选值。
5. 二分法实现
- 初始化二分法的左右边界,左边界为矩阵中的最小值,右边界为矩阵中的最大值。
- 在每次迭代中,计算中间值 ( mid ),并检查是否满足条件。
- 根据检查结果调整左右边界,直到找到最小的 ( kth )。
总结
通过将问题转化为二分图匹配,并使用二分法来枚举可能的第 ( K ) 大的数,我们可以高效地找到满足条件的最小值。这种方法避免了暴力枚举,大大减少了计算量。
二、JavaScript算法源码
以下是对代码的详细注释和讲解,帮助你理解每一部分的逻辑和实现方式。
代码结构
- 输入处理:读取输入的矩阵和参数。
- 二分枚举:通过二分法枚举可能的第 ( K ) 大的最小值。
- 检查函数:检查当前枚举的值是否满足条件。
- DFS 实现二分图匹配:通过深度优先搜索(DFS)实现二分图的最大匹配。
详细注释和讲解
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;void (async function () {// 读取输入的第一行,解析出 N, M, Kconst [n, m, k] = (await readline()).split(" ").map(Number);// 初始化二分枚举的左右边界let min = 1; // 最小可能值let max = -Infinity; // 最大可能值,初始为负无穷// 读取矩阵const matrix = [];for (let i = 0; i < n; i++) {matrix.push((await readline()).split(" ").map(Number)); // 将每一行转换为数字数组max = Math.max(max, ...matrix[i]); // 更新最大值}// 二分枚举第 K 大的最小取值while (min <= max) {// mid 是被枚举出来的 N 个数中的第 K 大的最小取值const mid = (min + max) >> 1; // 取中间值,相当于 Math.floor((min + max) / 2)// 检查 mid 是否可以作为 N 个数中第 K 大的值if (check(mid)) {// 如果满足条件,尝试更小的值max = mid - 1;} else {// 如果不满足条件,尝试更大的值min = mid + 1;}}// 输出结果console.log(min);// 检查函数:判断当前枚举的 kth 是否满足条件function check(kth) {// 利用二分图最大匹配来求解,小于等于 kth 的元素个数(即二分图最大匹配)let smallerCount = 0;// 记录每个列号的匹配成功的行号// 初始时每个列号都处于未配对状态,此时将列号配对的行号赋值为 -1const match = new Array(m).fill(-1);// 遍历行号,每个行号对互相心仪的列号发起配对请求for (let i = 0; i < n; i++) {// 记录增广路访问过的列号const vis = new Array(m).fill(false);// 如果当前行号 i 可以找到匹配的列号,则 smallerCount + 1if (dfs(i, kth, match, vis)) {smallerCount++;}}// 判断是否满足条件:小于等于 kth 的元素个数是否 >= N - K + 1return smallerCount >= n - k + 1;}// DFS 实现二分图匹配function dfs(i, kth, match, vis) {// 行号 i 发起了配对请求// 遍历每一个列号 jfor (let j = 0; j < m; j++) {// 如果当前列号 j 未被增广路探索过 && 当前行 i 列 j 的元素值 <= kthif (!vis[j] && matrix[i][j] <= kth) {vis[j] = true; // 标记列号 j 为已访问// 如果列号 j 未配对,或者已配对但可以找到其他行号重新配对if (match[j] == -1 || dfs(match[j], kth, match, vis)) {// 则当前行号 i 和列号 j 可以配对match[j] = i;return true;}}}// 如果找不到匹配的列号,返回 falsereturn false;}
})();
代码逻辑详解
1. 输入处理
- 使用
readline模块读取输入。 - 解析第一行得到 ( N )、( M )、( K )。
- 读取矩阵,并记录矩阵中的最大值
max,作为二分枚举的右边界。
2. 二分枚举
- 初始化二分枚举的左右边界:
min = 1:最小值从 1 开始。max:矩阵中的最大值。
- 通过二分法枚举可能的第 ( K ) 大的最小值
mid。 - 调用
check(mid)检查当前mid是否满足条件。
3. 检查函数 check(kth)
- 目标:检查是否存在至少 ( N - K + 1 ) 个小于等于
kth的元素,并且这些元素不在同一行或同一列。 - 实现方式:
- 使用二分图最大匹配算法。
- 遍历每一行,尝试匹配一个列号。
- 如果匹配成功,则
smallerCount + 1。 - 最终判断
smallerCount是否大于等于 ( N - K + 1 )。
4. DFS 实现二分图匹配
- 目标:为当前行号
i找到一个匹配的列号j。 - 实现方式:
- 遍历所有列号
j。 - 如果列号
j未被访问过,并且矩阵中matrix[i][j] <= kth,则尝试匹配。 - 如果列号
j未配对,或者已配对但可以找到其他行号重新配对,则匹配成功。 - 返回匹配结果。
- 遍历所有列号
5. 输出结果
- 当二分枚举结束时,
min即为满足条件的最小值。
关键点总结
- 二分枚举:通过二分法高效枚举可能的第 ( K ) 大的最小值。
- 二分图匹配:将问题转化为二分图的最大匹配问题,确保选出的数不在同一行或同一列。
- DFS 实现匹配:通过 DFS 实现二分图的匹配过程,确保匹配的列号满足条件。
通过以上注释和讲解,你应该能够理解代码的每一部分逻辑和实现方式。如果还有疑问,欢迎随时提出!
三、Java算法源码
代码结构
- 输入处理:读取输入的矩阵和参数。
- 二分枚举:通过二分法枚举可能的第 ( K ) 大的最小值。
- 检查函数:检查当前枚举的值是否满足条件。
- DFS 实现二分图匹配:通过深度优先搜索(DFS)实现二分图的最大匹配。
详细注释和讲解
import java.util.Arrays;
import java.util.Scanner;public class Main {// 定义全局变量static int n; // 矩阵的行数static int m; // 矩阵的列数static int k; // 第 K 大static int[][] matrix; // 存储矩阵public static void main(String[] args) {Scanner sc = new Scanner(System.in);// 读取输入的第一行,解析出 N, M, Kn = sc.nextInt();m = sc.nextInt();k = sc.nextInt();// 初始化二分枚举的左右边界int min = 1; // 最小可能值int max = Integer.MIN_VALUE; // 最大可能值,初始为整型最小值// 读取矩阵matrix = new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {matrix[i][j] = sc.nextInt(); // 读取矩阵元素max = Math.max(max, matrix[i][j]); // 更新最大值}}// 二分枚举第 K 大的最小取值while (min <= max) {// mid 是被枚举出来的 N 个数中的第 K 大的最小取值int mid = (min + max) >> 1; // 取中间值,相当于 (min + max) / 2// 检查 mid 是否可以作为 N 个数中第 K 大的值if (check(mid)) {// 如果满足条件,尝试更小的值max = mid - 1;} else {// 如果不满足条件,尝试更大的值min = mid + 1;}}// 输出结果System.out.println(min);}// 检查函数:判断当前枚举的 kth 是否满足条件public static boolean check(int kth) {// 利用二分图最大匹配来求解,小于等于 kth 的元素个数(即二分图最大匹配)int smallerCount = 0;// 记录每个列号的匹配成功的行号int[] match = new int[m];// 初始时每个列号都处于未配对状态,此时将列号配对的行号赋值为 -1Arrays.fill(match, -1);// 遍历行号,每个行号对互相心仪的列号发起配对请求for (int i = 0; i < n; i++) {// 记录增广路访问过的列号boolean[] vis = new boolean[m];// 如果当前行号 i 可以找到匹配的列号,则 smallerCount + 1if (dfs(i, kth, match, vis)) {smallerCount++;}}// 判断是否满足条件:小于等于 kth 的元素个数是否 >= N - K + 1return smallerCount >= n - k + 1;}// DFS 实现二分图匹配public static boolean dfs(int i, int kth, int[] match, boolean[] vis) {// 行号 i 发起了配对请求// 遍历每一个列号 jfor (int j = 0; j < m; j++) {// 如果当前列号 j 未被增广路探索过 && 当前行 i 列 j 的元素值 <= kthif (!vis[j] && matrix[i][j] <= kth) {vis[j] = true; // 标记列号 j 为已访问// 如果列号 j 未配对,或者已配对但可以找到其他行号重新配对if (match[j] == -1 || dfs(match[j], kth, match, vis)) {// 则当前行号 i 和列号 j 可以配对match[j] = i;return true;}}}// 如果找不到匹配的列号,返回 falsereturn false;}
}
代码逻辑详解
1. 输入处理
- 使用
Scanner读取输入。 - 解析第一行得到 ( N )、( M )、( K )。
- 读取矩阵,并记录矩阵中的最大值
max,作为二分枚举的右边界。
2. 二分枚举
- 初始化二分枚举的左右边界:
min = 1:最小值从 1 开始。max:矩阵中的最大值。
- 通过二分法枚举可能的第 ( K ) 大的最小值
mid。 - 调用
check(mid)检查当前mid是否满足条件。
3. 检查函数 check(kth)
- 目标:检查是否存在至少 ( N - K + 1 ) 个小于等于
kth的元素,并且这些元素不在同一行或同一列。 - 实现方式:
- 使用二分图最大匹配算法。
- 遍历每一行,尝试匹配一个列号。
- 如果匹配成功,则
smallerCount + 1。 - 最终判断
smallerCount是否大于等于 ( N - K + 1 )。
4. DFS 实现二分图匹配
- 目标:为当前行号
i找到一个匹配的列号j。 - 实现方式:
- 遍历所有列号
j。 - 如果列号
j未被访问过,并且矩阵中matrix[i][j] <= kth,则尝试匹配。 - 如果列号
j未配对,或者已配对但可以找到其他行号重新配对,则匹配成功。 - 返回匹配结果。
- 遍历所有列号
5. 输出结果
- 当二分枚举结束时,
min即为满足条件的最小值。
关键点总结
- 二分枚举:通过二分法高效枚举可能的第 ( K ) 大的最小值。
- 二分图匹配:将问题转化为二分图的最大匹配问题,确保选出的数不在同一行或同一列。
- DFS 实现匹配:通过 DFS 实现二分图的匹配过程,确保匹配的列号满足条件。
通过以上注释和讲解,你应该能够理解代码的每一部分逻辑和实现方式。如果还有疑问,欢迎随时提出!
四、Python算法源码
以下是对 Python 代码的详细注释和讲解,帮助你理解每一部分的逻辑和实现方式。
代码结构
- 输入处理:读取输入的矩阵和参数。
- 二分枚举:通过二分法枚举可能的第 ( K ) 大的最小值。
- 检查函数:检查当前枚举的值是否满足条件。
- DFS 实现二分图匹配:通过深度优先搜索(DFS)实现二分图的最大匹配。
详细注释和讲解
import sys# 输入获取
n, m, k = map(int, input().split()) # 读取 N, M, K
matrix = [list(map(int, input().split())) for _ in range(n)] # 读取矩阵# DFS 实现二分图匹配
def dfs(i, kth, match, vis):"""为行号 i 找到一个匹配的列号 j。:param i: 当前行号:param kth: 当前枚举的第 K 大值:param match: 记录列号匹配的行号:param vis: 记录列号是否被访问过:return: 是否找到匹配"""# 遍历每一个列号 jfor j in range(m):# 如果列号 j 未被访问过,并且矩阵中 matrix[i][j] <= kthif not vis[j] and matrix[i][j] <= kth:vis[j] = True # 标记列号 j 为已访问# 如果列号 j 未配对,或者已配对但可以找到其他行号重新配对if match[j] == -1 or dfs(match[j], kth, match, vis):# 则当前行号 i 和列号 j 可以配对match[j] = ireturn True# 如果找不到匹配的列号,返回 Falsereturn False# 检查函数
def check(kth):"""检查当前枚举的 kth 是否满足条件。:param kth: 当前枚举的第 K 大值:return: 是否满足条件"""# 利用二分图最大匹配来求解,小于等于 kth 的元素个数(即二分图最大匹配)smallerCount = 0# 记录每个列号的匹配成功的行号# 初始时每个列号都处于未配对状态,此时将列号配对的行号赋值为 -1match = [-1] * m# 遍历行号,每个行号对互相心仪的列号发起配对请求for i in range(n):# 记录增广路访问过的列号vis = [False] * m# 如果当前行号 i 可以找到匹配的列号,则 smallerCount + 1if dfs(i, kth, match, vis):smallerCount += 1# 判断是否满足条件:小于等于 kth 的元素个数是否 >= N - K + 1return smallerCount >= n - k + 1# 算法入口
def getResult():"""主函数,通过二分枚举找到第 K 大的最小值。:return: 第 K 大的最小值"""low = 1 # 二分枚举的左边界high = -sys.maxsize # 二分枚举的右边界,初始为系统最小值# 找到矩阵中的最大值,作为二分枚举的右边界for i in range(n):for j in range(m):high = max(high, matrix[i][j])# 二分枚举第 K 大的最小取值while low <= high:# mid 是被枚举出来的 N 个数中的第 K 大的最小取值mid = (low + high) >> 1 # 取中间值,相当于 (low + high) // 2# 检查 mid 是否可以作为 N 个数中第 K 大的值if check(mid):# 如果满足条件,尝试更小的值high = mid - 1else:# 如果不满足条件,尝试更大的值low = mid + 1# 返回结果return low# 算法调用
print(getResult())
代码逻辑详解
1. 输入处理
- 使用
input()读取输入。 - 解析第一行得到 ( N )、( M )、( K )。
- 读取矩阵,并存储在
matrix中。
2. 二分枚举
- 初始化二分枚举的左右边界:
low = 1:最小值从 1 开始。high:矩阵中的最大值。
- 通过二分法枚举可能的第 ( K ) 大的最小值
mid。 - 调用
check(mid)检查当前mid是否满足条件。
3. 检查函数 check(kth)
- 目标:检查是否存在至少 ( N - K + 1 ) 个小于等于
kth的元素,并且这些元素不在同一行或同一列。 - 实现方式:
- 使用二分图最大匹配算法。
- 遍历每一行,尝试匹配一个列号。
- 如果匹配成功,则
smallerCount + 1。 - 最终判断
smallerCount是否大于等于 ( N - K + 1 )。
4. DFS 实现二分图匹配
- 目标:为当前行号
i找到一个匹配的列号j。 - 实现方式:
- 遍历所有列号
j。 - 如果列号
j未被访问过,并且矩阵中matrix[i][j] <= kth,则尝试匹配。 - 如果列号
j未配对,或者已配对但可以找到其他行号重新配对,则匹配成功。 - 返回匹配结果。
- 遍历所有列号
5. 输出结果
- 当二分枚举结束时,
low即为满足条件的最小值。
关键点总结
- 二分枚举:通过二分法高效枚举可能的第 ( K ) 大的最小值。
- 二分图匹配:将问题转化为二分图的最大匹配问题,确保选出的数不在同一行或同一列。
- DFS 实现匹配:通过 DFS 实现二分图的匹配过程,确保匹配的列号满足条件。
五、C/C++算法源码:
以下是 C语言 和 C++ 版本的代码,并附带详细的中文注释和讲解。
C语言代码
#include <stdio.h>
#include <limits.h>
#include <math.h>#define MAX_SIZE 150#define bool int
#define TRUE 1
#define FALSE 0int n, m, k;
int matrix[MAX_SIZE][MAX_SIZE];// DFS 实现二分图匹配
bool dfs(int i, int kth, int match[], int vis[]) {// 行号 i 发起了配对请求// 遍历每一个列号 jfor (int j = 0; j < m; j++) {// 如果列号 j 未被访问过,并且矩阵中 matrix[i][j] <= kthif (!vis[j] && matrix[i][j] <= kth) {vis[j] = TRUE; // 标记列号 j 为已访问// 如果列号 j 未配对,或者已配对但可以找到其他行号重新配对if (match[j] == -1 || dfs(match[j], kth, match, vis)) {// 则当前行号 i 和列号 j 可以配对match[j] = i;return TRUE;}}}// 如果找不到匹配的列号,返回 FALSEreturn FALSE;
}// 检查函数:判断当前枚举的 kth 是否满足条件
bool check(int kth) {// 利用二分图最大匹配来求解,小于等于 kth 的元素个数(即二分图最大匹配)int smallerCount = 0;// 记录每个列号的匹配成功的行号int match[m];// 初始时每个列号都处于未配对状态,此时将列号配对的行号赋值为 -1for (int i = 0; i < m; i++) match[i] = -1;// 遍历行号,每个行号对互相心仪的列号发起配对请求for (int i = 0; i < n; i++) {// 记录增广路访问过的列号int vis[MAX_SIZE] = {FALSE};// 如果当前行号 i 可以找到匹配的列号,则 smallerCount + 1if (dfs(i, kth, match, vis)) {smallerCount++;}}// 判断是否满足条件:小于等于 kth 的元素个数是否 >= N - K + 1return smallerCount >= (n - k + 1);
}int main() {// 读取输入的 N, M, Kscanf("%d %d %d", &n, &m, &k);int min = 1; // 二分枚举的左边界int max = INT_MIN; // 二分枚举的右边界,初始为整型最小值// 读取矩阵,并找到矩阵中的最大值for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {scanf("%d", &matrix[i][j]);max = (int) fmax(max, matrix[i][j]); // 更新最大值}}// 二分枚举第 K 大的最小取值while (min <= max) {// mid 是被枚举出来的 N 个数中的第 K 大的最小取值int mid = (min + max) >> 1; // 取中间值,相当于 (min + max) / 2// 检查 mid 是否可以作为 N 个数中第 K 大的值if (check(mid)) {// 如果满足条件,尝试更小的值max = mid - 1;} else {// 如果不满足条件,尝试更大的值min = mid + 1;}}// 输出结果printf("%d\n", min);return 0;
}
C++代码
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>using namespace std;const int MAX_SIZE = 150;int n, m, k;
vector<vector<int>> matrix(MAX_SIZE, vector<int>(MAX_SIZE));// DFS 实现二分图匹配
bool dfs(int i, int kth, vector<int>& match, vector<bool>& vis) {// 行号 i 发起了配对请求// 遍历每一个列号 jfor (int j = 0; j < m; j++) {// 如果列号 j 未被访问过,并且矩阵中 matrix[i][j] <= kthif (!vis[j] && matrix[i][j] <= kth) {vis[j] = true; // 标记列号 j 为已访问// 如果列号 j 未配对,或者已配对但可以找到其他行号重新配对if (match[j] == -1 || dfs(match[j], kth, match, vis)) {// 则当前行号 i 和列号 j 可以配对match[j] = i;return true;}}}// 如果找不到匹配的列号,返回 falsereturn false;
}// 检查函数:判断当前枚举的 kth 是否满足条件
bool check(int kth) {// 利用二分图最大匹配来求解,小于等于 kth 的元素个数(即二分图最大匹配)int smallerCount = 0;// 记录每个列号的匹配成功的行号vector<int> match(m, -1); // 初始时每个列号都处于未配对状态// 遍历行号,每个行号对互相心仪的列号发起配对请求for (int i = 0; i < n; i++) {// 记录增广路访问过的列号vector<bool> vis(m, false);// 如果当前行号 i 可以找到匹配的列号,则 smallerCount + 1if (dfs(i, kth, match, vis)) {smallerCount++;}}// 判断是否满足条件:小于等于 kth 的元素个数是否 >= N - K + 1return smallerCount >= (n - k + 1);
}int main() {// 读取输入的 N, M, Kcin >> n >> m >> k;int minVal = 1; // 二分枚举的左边界int maxVal = INT_MIN; // 二分枚举的右边界,初始为整型最小值// 读取矩阵,并找到矩阵中的最大值for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {cin >> matrix[i][j];maxVal = max(maxVal, matrix[i][j]); // 更新最大值}}// 二分枚举第 K 大的最小取值while (minVal <= maxVal) {// mid 是被枚举出来的 N 个数中的第 K 大的最小取值int mid = (minVal + maxVal) >> 1; // 取中间值,相当于 (minVal + maxVal) / 2// 检查 mid 是否可以作为 N 个数中第 K 大的值if (check(mid)) {// 如果满足条件,尝试更小的值maxVal = mid - 1;} else {// 如果不满足条件,尝试更大的值minVal = mid + 1;}}// 输出结果cout << minVal << endl;return 0;
}
代码逻辑详解
1. 输入处理
- 读取输入的 ( N )、( M )、( K )。
- 读取矩阵,并找到矩阵中的最大值
maxVal,作为二分枚举的右边界。
2. 二分枚举
- 初始化二分枚举的左右边界:
minVal = 1:最小值从 1 开始。maxVal:矩阵中的最大值。
- 通过二分法枚举可能的第 ( K ) 大的最小值
mid。 - 调用
check(mid)检查当前mid是否满足条件。
3. 检查函数 check(kth)
- 目标:检查是否存在至少 ( N - K + 1 ) 个小于等于
kth的元素,并且这些元素不在同一行或同一列。 - 实现方式:
- 使用二分图最大匹配算法。
- 遍历每一行,尝试匹配一个列号。
- 如果匹配成功,则
smallerCount + 1。 - 最终判断
smallerCount是否大于等于 ( N - K + 1 )。
4. DFS 实现二分图匹配
- 目标:为当前行号
i找到一个匹配的列号j。 - 实现方式:
- 遍历所有列号
j。 - 如果列号
j未被访问过,并且矩阵中matrix[i][j] <= kth,则尝试匹配。 - 如果列号
j未配对,或者已配对但可以找到其他行号重新配对,则匹配成功。 - 返回匹配结果。
- 遍历所有列号
5. 输出结果
- 当二分枚举结束时,
minVal即为满足条件的最小值。
关键点总结
- 二分枚举:通过二分法高效枚举可能的第 ( K ) 大的最小值。
- 二分图匹配:将问题转化为二分图的最大匹配问题,确保选出的数不在同一行或同一列。
- DFS 实现匹配:通过 DFS 实现二分图的匹配过程,确保匹配的列号满足条件。
通过以上注释和讲解,你应该能够理解代码的每一部分逻辑和实现方式。如果还有疑问,欢迎随时提出!
六、尾言
什么是华为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 或监考人员进行反馈。
祝你考试顺利,取得理想成绩!
相关文章:
【2024年华为OD机试】 (C卷,200分)- 矩阵匹配(JavaScriptJava PythonC/C++)
一、问题描述 问题描述 给定一个大小为 ( N \times M )(( N \leq M ))的矩阵,从中选出 ( N ) 个数,要求任意两个数字不能在同一行或同一列。求选出来的 ( N ) 个数中第 ( K ) 大的数字的最小值。 输入描述 输入矩阵要求&#…...
FileReader使用
FileReader : 读取文件内容的api,,,在前端处理上传的文件,,比如预览图片 readAsDataURL(file) : 读取为base64编码的 data urlreadAsText() : 读取为文本readAsArrayBuffer() : 读取为二进制 …...
AI 浪潮席卷中国年,开启科技新春新纪元
在这博主提前祝大家蛇年快乐呀!!! 随着人工智能(AI)技术的飞速发展,其影响力已经渗透到社会生活的方方面面。在中国传统节日 —— 春节期间,AI 技术也展现出了巨大的潜力,为中国年带…...
Python 数据分析 - Matplotlib 绘图
Python 数据分析 - Matplotlib 绘图 简介绘图折线图单线多线子图 散点图直方图条形图纵置横置多条 饼图 简介 Matplotlib 是 Python 提供的一个绘图库,通过该库我们可以很容易的绘制出折线图、直方图、散点图、饼图等丰富的统计图,安装使用 pip install…...
适配器模式——C++实现
目录 1. 适配器模式简介 2. 角色组成 3. 代码示例 4. 适配器模式、装饰器模式、外观模式的辨析 1. 适配器模式简介 适配器模式是一种结构型模式。 适配器模式的定义:适配器模式将一个类的接口,转换成客户期望的另一个接口。适配器让原本接口不可兼容…...
搭建Spark分布式集群
1,下载 下载 spark-3.5.4-bin-without-hadoop.tgz 地址: https://downloads.apache.org/spark/spark-3.5.4/ 2,安装 通过虚拟机设置共享文件夹将需要的安装包复制到linux虚拟机中 localhost1。虚拟机的共享盘在 /mnt/hgfs/。 将共享盘安装…...
doris:STRUCT
STRUCT<field_name:field_type [COMMENT comment_string], ... > 表示由多个 Field 组成的结构体,也可被理解为多个列的集合。 不能作为 Key 使用,目前 STRUCT 仅支持在 Duplicate 模型的表中使用。一个 Struct 中的 Field 的名字和数量固定&…...
【Java基础-41.5】深入解析Java异常链:构建清晰的错误追踪体系
在Java编程中,异常处理是保证程序健壮性和可维护性的重要部分。然而,在实际开发中,异常往往不是孤立发生的,而是由一系列相关的异常引发的。为了更好地理解和处理这种复杂的异常场景,Java引入了 异常链(Exc…...
新年祝词(原创)
新年将至,福进万户。 家家团圆,事事顺心。 喜迎财神,多寿添金。 瑞兽迎春,炮竹声起。 趋吉避凶,蛇年大吉。 中华崛起,人人自强。 天下大同,百姓富足。 有情有义,平易近人。 …...
线上突发:MySQL 自增 ID 用完,怎么办?
线上突发:MySQL 自增 ID 用完,怎么办? 1. 问题背景2. 场景复现3. 自增id用完怎么办?4. 总结 1. 问题背景 最近,我们在数据库巡检的时候发现了一个问题:线上的地址表自增主键用的是int类型。随着业务越做越…...
ESP32 I2S音频总线学习笔记(二):I2S读取INMP441音频数据
简介 在这个系列的上一篇文章中,我们介绍了ESP32 I2S音频总线的相关知识,简要了解了什么是I2S总线、它的通信格式,以及相关的底层API函数。没有看过上篇文章的可以点击文章进行回顾: ESP32 I2S音频总线学习笔记(一&a…...
一文简单回顾Java中的String、StringBuilder、StringBuffer
简单说下String、StringBuilder、StringBuffer的区别 String、StringBuffer、StringBuilder在Java中都是用于处理字符串的,它们之间的区别是String是不可变的,平常开发用的最多,当遇到大量字符串连接的时候,就用StringBuilder&am…...
matlab中,fill命令用法
在 MATLAB 中,fill 命令用于创建填充多边形的图形对象。使用 fill 可以在二维坐标系中绘制填充的区域,通常用于绘制图形的背景或显示数据分布。 基本语法 fill(X, Y, C)X 和 Y 是同样长度的向量,定义了多边形的顶点坐标。C 是颜色࿰…...
深入解析 Linux 内核内存管理核心:mm/memory.c
在 Linux 内核的众多组件中,内存管理模块是系统性能和稳定性的关键。mm/memory.c 文件作为内存管理的核心实现,承载着页面故障处理、页面表管理、内存区域映射与取消映射等重要功能。本文将深入探讨 mm/memory.c 的设计思想、关键机制以及其在内核中的作用,帮助读者更好地理…...
Ubuntu 16.04安装Lua
个人博客地址:Ubuntu 16.04安装Lua | 一张假钞的真实世界 在Linux系统上使用以下命令编译安装Lua: curl -R -O http://www.lua.org/ftp/lua-5.3.3.tar.gz tar zxf lua-5.3.3.tar.gz cd lua-5.3.3 make linux test 安装make 编译过程如果提示以下信息…...
vue中的el是指什么
简介: 在Vue.js中,el指的是Vue实例的挂载元素。 具体来说,el是一个选项,用于指定Vue实例应该挂载到哪个DOM元素上。通过这个选项,Vue可以知道应该从哪个元素开始进行模板编译和渲染。它可以是一个CSS选择器字符串&…...
计算机网络之链路层
本文章目录结构出自于《王道计算机考研 计算机网络_哔哩哔哩_bilibili》 02 数据链路层 在网上看到其他人做了详细的笔记,就不再多余写了,直接参考着学习吧。 1 详解数据链路层-数据链路层的功能【王道计算机网络笔记】_wx63088f6683f8f的技术博客_51C…...
Vue 3 30天精进之旅:Day 07 - Vue Router
引言 在前几天的学习中,我们深入探讨了Vue的表单输入绑定及其处理机制。今天,我们将学习Vue Router,这是Vue.js官方提供的路由管理器,用于构建单页面应用(SPA)。通过使用Vue Router,你可以轻松…...
lib.exe正确用法winhv.lib生成方法
lib.exe /def:winhv.def /OUT:winhv.lib /machine:x64 winhv.def注意是 winhv.sys要不然会变成dll LIBRARY winhv.sys EXPORTSWinHvAllocateOverlayPagesWinHvDisablePartitionVtlWinHvDisableVpVtlWinHvEnablePartitionVtlWinHvEnableVpVtlWinHvFreeOverlayPagesWinHvGetCurr…...
react-bn-面试
1.主要内容 工作台待办 实现思路: 1,待办list由后端返回,固定需要的字段有id(查详细)、type(本条待办的类型),还可能需要时间,状态等 2,一个集中处理待办中转路由页,所有待办都跳转到这个页面…...
Spring Boot Actuator 集成 Micrometer(官网文档解读)
目录 概述 实现 Observation 可观测性 Observation 功能核心类 ObservationPredicate GlobalObservationConvention ObservationFilter ObservationHandler ObservationRegistryCustomizer Observation 相关注解 多线程处理机制 配置上下文传播 常用标签配置 Open…...
Kotlin函数式API
Kotlin函数式API 1.maxBy val list listOf("Apple","Banana", "Orange","pear","Grape","Watermelon") val maxLengthFruit list.maxBy {it.length} println(maxLengthFruit) 2.map 集合中zhi的map函数是最…...
Linux:一切皆文件
**文件描述符**:它是一种特殊的索引,本质上是进程中file_struct结构体成员fd_array数组的下标。在Linux等系统中,文件描述符是一个非负整数,用于标识打开的文件,是内核为了高效管理已被打开的文件所创建的索引。通过文…...
【物联网】ARM核常用指令(详解):数据传送、计算、位运算、比较、跳转、内存访问、CPSR/SPSR、流水线及伪指令
文章目录 指令格式(重点)1. 立即数2. 寄存器位移 一、数据传送指令1. MOV指令2. MVN指令3. LDR指令 二、数据计算指令1. ADD指令1. SUB指令1. MUL指令 三、位运算指令1. AND指令2. ORR指令3. EOR指令4. BIC指令 四、比较指令五、跳转指令1. B/BL指令2. l…...
项目集成Nacos
文章目录 1.环境搭建1.创建模块 sunrays-common-cloud-nacos-starter2.目录结构3.pom.xml4.自动配置1.NacosAutoConfiguration.java2.spring.factories 5.引入cloud模块通用依赖 2.测试1.创建模块 sunrays-common-cloud-nacos-starter-demo2.目录结构3.pom.xml4.application.ym…...
QT交叉编译环境搭建(Cmake和qmake)
介绍一共有两种方法(基于qmake和cmake): 1.直接调用虚拟机中的交叉编译工具编译 2.在QT中新建编译套件kits camke和qmake的区别:CMake 和 qmake 都是自动化构建工具,用于简化构建过程,管理编译设置&…...
【某大厂一面】数组和链表区别
在 Java 中,数组(Array)和链表(LinkedList)是两种常见的数据结构,它们在存储和操作方式上有显著的区别。了解它们的差异有助于选择适合特定应用场景的结构。下面是数组和链表之间的详细比较。 1. 存储结构…...
基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结
title: 基于 Jenkins 的测试报告获取与处理并写入 Jira Wiki 的技术总结 tags: - jenkins - python categories: - jenkins在软件开发的持续集成与持续交付(CI/CD)流程里,及时、准确地获取并分析测试报告对保障软件质量至关重要。本文将详细…...
一文大白话讲清楚webpack进阶——5——dev-server原理及其作用
文章目录 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用1. webpack的作用2. dev-server的作用3. dev-server的原理3.1 啥是webpack-dev-middleware3.2 HMR 一文大白话讲清楚webpack进阶——5——dev-server原理及其作用 1. webpack的作用 webpack的作用我们之…...
[cg] 使用snapgragon 对UE5.3抓帧
最近想要抓opengl 的api,renderdoc在起应用时会闪退(具体原因还不知道),试了下snapgraon, 还是可以的 官网需要注册登录后下载,官网路径:Developer | Qualcomm 为了方便贴上已经下载好的exe安装包&#x…...
