【2024年华为OD机试】 (E卷,100分) - 路灯照明问题(JavaScriptJava PythonC/C++)
一、问题描述
题目解析
题目描述
在一条笔直的公路上安装了N个路灯,从位置0开始安装,路灯之间的间距固定为100米。每个路灯都有自己的照明半径。要求计算第一个路灯和最后一个路灯之间,无法照明的区间的长度和。
输入描述
- 第一行为一个数N,表示路灯个数,1 <= N <= 100000。
- 第二行为N个空格分隔的数,表示路灯的照明半径,1 <= 照明半径 <= 100000 * 100。
输出描述
- 第一个路灯和最后一个路灯之间,无法照明的区间的长度和。
示例
示例1
输入
2
50 50
输出
0
说明
- 路灯1覆盖0-50米。
- 路灯2覆盖50-100米。
- 路灯1和路灯2之间(0米-100米)无未覆盖的区间。
示例2
输入
4
50 70 20 70
输出
20
说明
- 路灯1覆盖0-50米。
- 路灯2覆盖30-170米。
- 路灯3覆盖180-220米。
- 路灯4覆盖230-370米。
- 未覆盖的区间为[170,180]和[220,230],总长度为20米。
解题思路
-
确定每个路灯的覆盖范围:
- 每个路灯的位置为
i * 100
米,其中i
为路灯的索引(从0开始)。 - 每个路灯的覆盖范围为
[i * 100 - r, i * 100 + r]
,其中r
为照明半径。
- 每个路灯的位置为
-
合并重叠的覆盖范围:
- 将所有路灯的覆盖范围按照起始位置进行排序。
- 遍历所有覆盖范围,合并重叠的部分,得到一组不重叠的覆盖区间。
-
计算未覆盖的区间:
- 遍历合并后的覆盖区间,计算相邻区间之间的未覆盖部分。
- 将这些未覆盖部分的长度累加,得到最终的结果。
关键点
- 覆盖范围的合并:需要将重叠的覆盖范围合并为一个更大的区间,以避免重复计算。
- 未覆盖区间的计算:在合并后的覆盖区间之间,可能存在未覆盖的部分,需要仔细计算这些部分的长度。
复杂度分析
- 时间复杂度:O(N log N),主要是由于对覆盖范围进行排序。
- 空间复杂度:O(N),用于存储覆盖范围和合并后的区间。
通过以上步骤,可以有效地计算出第一个路灯和最后一个路灯之间无法照明的区间的长度和。
二、JavaScript算法源码
以下是代码的详细注释和逐行讲解:
代码逐行解析
1. 初始化输入读取
const readline = require("readline");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const lines = [];
- 使用
readline
模块创建一个接口rl
,用于从标准输入读取数据。 lines
数组用于存储输入的行数据。
2. 读取输入并处理
rl.on("line", (line) => {
lines.push(line);
if (lines.length === 2) {
// 处理输入
}
});
- 监听
line
事件,每次读取一行输入并将其存入lines
数组。 - 当
lines
数组的长度为 2 时,表示已经读取完所有输入(路灯数量n
和照明半径数组),开始处理。
3. 解析输入数据
let n = lines[0] - 0;
let arr = lines[1]
.split(" ")
.slice(0, n)
.map((ele, idx) => {
return [idx * 100 - ele < 0 ? 0 : idx * 100 - ele, ele - 0 + idx * 100];
})
.sort((a, b) => a[0] - b[0]);
n
:将第一行输入转换为数字,表示路灯数量。arr
:处理第二行输入:- 使用
split(" ")
将字符串按空格分割成数组。 - 使用
slice(0, n)
确保只取前n
个照明半径。 - 使用
map
将每个照明半径转换为覆盖范围[left, right]
:left = idx * 100 - ele < 0 ? 0 : idx * 100 - ele
:计算左边界,确保不小于 0。right = ele - 0 + idx * 100
:计算右边界。
- 使用
sort((a, b) => a[0] - b[0])
按左边界升序排序。
- 使用
4. 合并覆盖范围并计算未覆盖区间
let gap = 0;
let [start, end] = arr[0];
for (let i = 1; i < arr.length; i++) {
if (arr[i][0] > end) {
gap += arr[i][0] - end;
[start, end] = arr[i];
} else {
end = Math.max(end, arr[i][1]);
}
}
gap
:用于存储未覆盖区间的总长度。[start, end]
:初始化当前覆盖范围为第一个路灯的覆盖范围。- 遍历所有路灯的覆盖范围:
- 如果当前覆盖范围的左边界大于
end
,说明存在未覆盖区间:- 计算未覆盖区间的长度
arr[i][0] - end
,并累加到gap
。 - 更新
[start, end]
为当前覆盖范围。
- 计算未覆盖区间的长度
- 如果当前覆盖范围与上一个范围重叠,则合并范围,更新
end
为两者的最大值。
- 如果当前覆盖范围的左边界大于
5. 输出结果
console.log(gap);
lines.length = 0;
- 输出未覆盖区间的总长度
gap
。 - 清空
lines
数组,以便处理下一组输入。
代码逻辑总结
-
输入处理:
- 读取路灯数量
n
和照明半径数组。 - 计算每个路灯的覆盖范围
[left, right]
,并按左边界排序。
- 读取路灯数量
-
合并覆盖范围:
- 遍历所有路灯的覆盖范围,合并重叠的部分。
-
计算未覆盖区间:
- 遍历合并后的覆盖范围,计算相邻区间之间的未覆盖部分。
-
输出结果:
- 输出未覆盖区间的总长度。
示例运行
输入 1
2
50 50
输出 1
0
解释:
- 路灯 1 覆盖范围:
[0, 50]
。 - 路灯 2 覆盖范围:
[50, 150]
。 - 合并后的覆盖范围:
[0, 150]
。 - 未覆盖区间长度:
0
。
输入 2
4
50 70 20 70
输出 2
20
解释:
- 路灯 1 覆盖范围:
[0, 50]
。 - 路灯 2 覆盖范围:
[30, 170]
。 - 路灯 3 覆盖范围:
[180, 220]
。 - 路灯 4 覆盖范围:
[230, 370]
。 - 合并后的覆盖范围:
[0, 170]
,[180, 220]
,[230, 370]
。 - 未覆盖区间:
[170, 180]
和[220, 230]
,总长度:20
。
输入 3
3
100 50 200
输出 3
0
解释:
- 路灯 1 覆盖范围:
[0, 100]
。 - 路灯 2 覆盖范围:
[50, 250]
。 - 路灯 3 覆盖范围:
[100, 500]
。 - 合并后的覆盖范围:
[0, 500]
。 - 未覆盖区间长度:
0
。
代码特点
-
覆盖范围的计算:
- 使用
idx * 100 - ele < 0 ? 0 : idx * 100 - ele
确保左边界不小于 0。 - 使用
ele - 0 + idx * 100
计算右边界。
- 使用
-
合并覆盖范围:
- 通过比较当前范围的左边界和上一个范围的右边界,判断是否重叠。
- 如果重叠,则合并范围;否则,计算未覆盖区间。
-
未覆盖区间的计算:
- 遍历合并后的覆盖范围,计算相邻区间之间的未覆盖部分。
通过以上注释和讲解,可以清晰地理解代码的逻辑和实现细节。
三、Java算法源码
以下是代码的详细解析和优化建议:
代码解析
1. 输入处理
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] lights = new int[n][2];
for (int i = 0; i < n; i++) {
int radius = sc.nextInt();
int left = Math.max(i * 100 - radius, 0);
int right = radius + i * 100;
lights[i][0] = left;
lights[i][1] = right;
}
- 读取路灯数量
n
和每个路灯的照明半径。 - 计算每个路灯的覆盖范围
[left, right]
:left = Math.max(i * 100 - radius, 0)
:确保左边界不小于 0。right = radius + i * 100
:右边界为路灯位置加上照明半径。
- 将每个路灯的覆盖范围存储在二维数组
lights
中。
2. 合并重叠的覆盖范围
List<int[]> intervals = new ArrayList<>();
int start = lights[0][0];
int end = lights[0][1];
for (int i = 1; i < n; i++) {
if (lights[i][0] > end) {
intervals.add(new int[]{start, end});
start = lights[i][0];
end = lights[i][1];
} else {
end = Math.max(end, lights[i][1]);
}
}
intervals.add(new int[]{start, end});
- 初始化
start
和end
为第一个路灯的覆盖范围。 - 遍历所有路灯的覆盖范围:
- 如果当前路灯的覆盖范围与上一个范围不重叠(
lights[i][0] > end
),则将上一个范围加入intervals
,并更新start
和end
。 - 如果重叠,则合并范围,更新
end
为两者的最大值。
- 如果当前路灯的覆盖范围与上一个范围不重叠(
- 最后将最后一个范围加入
intervals
。
3. 计算未覆盖的区间
int from = intervals.get(0)[1];
int gap = 0;
for (int i = 1; i < intervals.size(); i++) {
int to = intervals.get(i)[0];
gap += to - from;
from = intervals.get(i)[1];
}
System.out.println(gap);
- 初始化
from
为第一个覆盖范围的右边界。 - 遍历
intervals
,计算相邻覆盖范围之间的未覆盖区间长度,并累加到gap
。 - 输出未覆盖区间的总长度。
优化建议
-
排序覆盖范围
- 当前代码假设路灯的覆盖范围已经按左边界排序。如果输入的路灯覆盖范围未排序,需要先对
lights
按左边界排序:Arrays.sort(lights, (a, b) -> Integer.compare(a[0], b[0]));
- 当前代码假设路灯的覆盖范围已经按左边界排序。如果输入的路灯覆盖范围未排序,需要先对
-
边界检查
- 如果
n == 1
,直接输出 0,因为只有一个路灯,没有未覆盖的区间。
- 如果
-
代码简化
- 可以将合并覆盖范围和计算未覆盖区间的逻辑合并为一个循环,减少代码量。
优化后的代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[][] lights = new int[n][2];
for (int i = 0; i < n; i++) {
int radius = sc.nextInt();
int left = Math.max(i * 100 - radius, 0);
int right = radius + i * 100;
lights[i][0] = left;
lights[i][1] = right;
}
// 按左边界排序
Arrays.sort(lights, (a, b) -> Integer.compare(a[0], b[0]));
// 合并覆盖范围
List<int[]> intervals = new ArrayList<>();
int start = lights[0][0];
int end = lights[0][1];
for (int i = 1; i < n; i++) {
if (lights[i][0] > end) {
intervals.add(new int[]{start, end});
start = lights[i][0];
end = lights[i][1];
} else {
end = Math.max(end, lights[i][1]);
}
}
intervals.add(new int[]{start, end});
// 计算未覆盖的区间
int gap = 0;
int from = intervals.get(0)[1];
for (int i = 1; i < intervals.size(); i++) {
int to = intervals.get(i)[0];
gap += to - from;
from = intervals.get(i)[1];
}
System.out.println(gap);
}
}
测试用例
输入 1
2
50 50
输出 1
0
输入 2
4
50 70 20 70
输出 2
20
输入 3
3
100 50 200
输出 3
0
复杂度分析
-
时间复杂度:
- 排序:
O(N log N)
。 - 合并覆盖范围:
O(N)
。 - 计算未覆盖区间:
O(N)
。 - 总时间复杂度:
O(N log N)
。
- 排序:
-
空间复杂度:
- 存储覆盖范围:
O(N)
。 - 存储合并后的区间:
O(N)
。 - 总空间复杂度:
O(N)
。
- 存储覆盖范围:
通过以上优化,代码更加健壮且高效,能够处理大规模输入。
四、Python算法源码
以下是代码的详细注释和逐行讲解:
代码逐行解析
1. 输入处理
n = int(input())
arr = list(map(int, input().split()))
n
:读取路灯的数量。arr
:读取每个路灯的照明半径,并将其存储在列表中。
2. 计算每个路灯的覆盖范围
for i in range(n):
tmp = arr[i]
l = max(i * 100 - tmp, 0)
r = tmp + i * 100
arr[i] = [l, r]
- 遍历每个路灯:
tmp
:当前路灯的照明半径。l = max(i * 100 - tmp, 0)
:计算当前路灯的覆盖范围的左边界。确保左边界不小于 0。r = tmp + i * 100
:计算当前路灯的覆盖范围的右边界。- 将当前路灯的覆盖范围
[l, r]
存入arr[i]
。
3. 合并重叠的覆盖范围
start, end = arr[0]
res = []
for i in range(n):
if arr[i][0] > end:
res.append([start, end])
start, end = arr[i]
else:
end = max(end, arr[i][1])
res.append([start, end])
- 初始化
start
和end
为第一个路灯的覆盖范围。 - 遍历所有路灯的覆盖范围:
- 如果当前路灯的覆盖范围的左边界大于
end
,说明当前范围与上一个范围不重叠:- 将上一个范围
[start, end]
加入res
。 - 更新
start
和end
为当前路灯的覆盖范围。
- 将上一个范围
- 如果当前路灯的覆盖范围与上一个范围重叠:
- 更新
end
为当前范围和上一个范围的右边界中的最大值。
- 更新
- 如果当前路灯的覆盖范围的左边界大于
- 将最后一个范围
[start, end]
加入res
。
4. 计算未覆盖的区间
start = res[0][1]
gap = 0
for i in range(1, len(res)):
end = res[i][0]
gap += end - start
start = res[i][1]
print(gap)
- 初始化
start
为第一个覆盖范围的右边界。 - 遍历
res
中的所有覆盖范围:end
:当前覆盖范围的左边界。- 计算未覆盖区间的长度
end - start
,并累加到gap
。 - 更新
start
为当前覆盖范围的右边界。
- 输出未覆盖区间的总长度
gap
。
代码逻辑总结
-
输入处理:
- 读取路灯数量和每个路灯的照明半径。
- 计算每个路灯的覆盖范围。
-
合并重叠的覆盖范围:
- 将所有路灯的覆盖范围按左边界排序(虽然没有显式排序,但路灯位置是递增的)。
- 合并重叠的覆盖范围,得到一组不重叠的区间。
-
计算未覆盖的区间:
- 遍历合并后的覆盖范围,计算相邻区间之间的未覆盖部分。
- 输出未覆盖区间的总长度。
示例运行
输入 1
2
50 50
输出 1
0
解释:
- 路灯 1 覆盖范围:
[0, 50]
。 - 路灯 2 覆盖范围:
[50, 150]
。 - 合并后的覆盖范围:
[0, 150]
。 - 未覆盖区间长度:
0
。
输入 2
4
50 70 20 70
输出 2
20
解释:
- 路灯 1 覆盖范围:
[0, 50]
。 - 路灯 2 覆盖范围:
[30, 170]
。 - 路灯 3 覆盖范围:
[180, 220]
。 - 路灯 4 覆盖范围:
[230, 370]
。 - 合并后的覆盖范围:
[0, 170]
,[180, 220]
,[230, 370]
。 - 未覆盖区间:
[170, 180]
和[220, 230]
,总长度:20
。
输入 3
3
100 50 200
输出 3
0
解释:
- 路灯 1 覆盖范围:
[0, 100]
。 - 路灯 2 覆盖范围:
[50, 250]
。 - 路灯 3 覆盖范围:
[100, 500]
。 - 合并后的覆盖范围:
[0, 500]
。 - 未覆盖区间长度:
0
。
代码特点
-
覆盖范围的计算:
- 使用
max(i * 100 - tmp, 0)
确保左边界不小于 0。 - 使用
tmp + i * 100
计算右边界。
- 使用
-
合并覆盖范围:
- 通过比较当前范围的左边界和上一个范围的右边界,判断是否重叠。
- 如果重叠,则合并范围;否则,将上一个范围加入结果列表。
-
未覆盖区间的计算:
- 遍历合并后的覆盖范围,计算相邻区间之间的未覆盖部分。
通过以上注释和讲解,可以清晰地理解代码的逻辑和实现细节。
五、C/C++算法源码:
以下是 C++ 和 C 代码的详细注释和逐行讲解:
C++ 代码解析
1. 输入处理
int n;
cin >> n;
vector<vector<int>> lights(n, vector<int>(2));
for (int i = 0; i < n; i++) {
int radius;
cin >> radius;
int left = max(i * 100 - radius, 0);
int right = radius + i * 100;
lights[i] = {left, right};
}
n
:读取路灯数量。lights
:存储每个路灯的覆盖范围[left, right]
。left = max(i * 100 - radius, 0)
:计算左边界,确保不小于 0。right = radius + i * 100
:计算右边界。
2. 合并重叠的覆盖范围
vector<vector<int>> intervals;
int start = lights[0][0];
int end = lights[0][1];
for (int i = 1; i < n; i++) {
if (lights[i][0] > end) {
intervals.push_back({start, end});
start = lights[i][0];
end = lights[i][1];
} else {
end = max(end, lights[i][1]);
}
}
intervals.push_back({start, end});
intervals
:存储合并后的不重叠覆盖范围。start
和end
:初始化当前覆盖范围为第一个路灯的覆盖范围。- 遍历所有路灯的覆盖范围:
- 如果当前覆盖范围的左边界大于
end
,说明不重叠:- 将上一个范围
[start, end]
加入intervals
。 - 更新
start
和end
为当前覆盖范围。
- 将上一个范围
- 如果重叠,则合并范围,更新
end
为两者的最大值。
- 如果当前覆盖范围的左边界大于
- 将最后一个范围
[start, end]
加入intervals
。
3. 计算未覆盖的区间
int from = intervals[0][1];
int gap = 0;
for (int i = 1; i < intervals.size(); i++) {
int to = intervals[i][0];
gap += to - from;
from = intervals[i][1];
}
cout << gap << endl;
from
:初始化当前右边界为第一个覆盖范围的右边界。gap
:存储未覆盖区间的总长度。- 遍历
intervals
:to
:当前覆盖范围的左边界。- 计算未覆盖区间的长度
to - from
,并累加到gap
。 - 更新
from
为当前覆盖范围的右边界。
- 输出未覆盖区间的总长度
gap
。
C 代码解析
1. 输入处理
int n;
scanf("%d", &n);
int lights[MAX_LIGHTS][2];
for (int i = 0; i < n; i++) {
int radius;
scanf("%d", &radius);
int left = (i * 100 - radius > 0) ? (i * 100 - radius) : 0;
int right = radius + i * 100;
lights[i][0] = left;
lights[i][1] = right;
}
n
:读取路灯数量。lights
:存储每个路灯的覆盖范围[left, right]
。left = (i * 100 - radius > 0) ? (i * 100 - radius) : 0
:计算左边界,确保不小于 0。right = radius + i * 100
:计算右边界。
2. 合并重叠的覆盖范围
int intervals[MAX_LIGHTS][2];
int intervalCount = 0;
int start = lights[0][0];
int end = lights[0][1];
for (int i = 1; i < n; i++) {
if (lights[i][0] > end) {
intervals[intervalCount][0] = start;
intervals[intervalCount][1] = end;
intervalCount++;
start = lights[i][0];
end = lights[i][1];
} else {
end = (end > lights[i][1]) ? end : lights[i][1];
}
}
intervals[intervalCount][0] = start;
intervals[intervalCount][1] = end;
intervalCount++;
intervals
:存储合并后的不重叠覆盖范围。intervalCount
:记录合并后的区间数量。start
和end
:初始化当前覆盖范围为第一个路灯的覆盖范围。- 遍历所有路灯的覆盖范围:
- 如果当前覆盖范围的左边界大于
end
,说明不重叠:- 将上一个范围
[start, end]
加入intervals
。 - 更新
start
和end
为当前覆盖范围。
- 将上一个范围
- 如果重叠,则合并范围,更新
end
为两者的最大值。
- 如果当前覆盖范围的左边界大于
- 将最后一个范围
[start, end]
加入intervals
。
3. 计算未覆盖的区间
int from = intervals[0][1];
int gap = 0;
for (int i = 1; i < intervalCount; i++) {
int to = intervals[i][0];
gap += to - from;
from = intervals[i][1];
}
printf("%d\n", gap);
from
:初始化当前右边界为第一个覆盖范围的右边界。gap
:存储未覆盖区间的总长度。- 遍历
intervals
:to
:当前覆盖范围的左边界。- 计算未覆盖区间的长度
to - from
,并累加到gap
。 - 更新
from
为当前覆盖范围的右边界。
- 输出未覆盖区间的总长度
gap
。
代码逻辑总结
-
输入处理:
- 读取路灯数量和每个路灯的照明半径。
- 计算每个路灯的覆盖范围
[left, right]
。
-
合并覆盖范围:
- 遍历所有路灯的覆盖范围,合并重叠的部分。
-
计算未覆盖区间:
- 遍历合并后的覆盖范围,计算相邻区间之间的未覆盖部分。
-
输出结果:
- 输出未覆盖区间的总长度。
示例运行
输入 1
2
50 50
输出 1
0
解释:
- 路灯 1 覆盖范围:
[0, 50]
。 - 路灯 2 覆盖范围:
[50, 150]
。 - 合并后的覆盖范围:
[0, 150]
。 - 未覆盖区间长度:
0
。
输入 2
4
50 70 20 70
输出 2
20
解释:
- 路灯 1 覆盖范围:
[0, 50]
。 - 路灯 2 覆盖范围:
[30, 170]
。 - 路灯 3 覆盖范围:
[180, 220]
。 - 路灯 4 覆盖范围:
[230, 370]
。 - 合并后的覆盖范围:
[0, 170]
,[180, 220]
,[230, 370]
。 - 未覆盖区间:
[170, 180]
和[220, 230]
,总长度:20
。
输入 3
3
100 50 200
输出 3
0
解释:
- 路灯 1 覆盖范围:
[0, 100]
。 - 路灯 2 覆盖范围:
[50, 250]
。 - 路灯 3 覆盖范围:
[100, 500]
。 - 合并后的覆盖范围:
[0, 500]
。 - 未覆盖区间长度:
0
。
通过以上注释和讲解,可以清晰地理解 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 或监考人员进行反馈。
祝你考试顺利,取得理想成绩!