一、问题描述
题目描述
小朋友出操,按学号从小到大排成一列;
小明来迟了,请你给小明出个主意,让他尽快找到他应该排的位置。
算法复杂度要求不高于nLog(n);学号为整数类型,队列规模 ≤ 10000;
输入描述
第一行:输入已排成队列的小朋友的学号(正整数),以","隔开;例如:
93,95,97,100,102,123,155
第二行:小明学号,如:
110
输出描述
输出一个数字,代表队列位置(从1开始)。例如:
6
用例
用例
输入
93,95,97,100,102,123,155
110
输出
6
题目解析
考察点
考察二分查找算法。
解析思路
- 问题理解:
- 本题要求在一个已排序的数组中找到目标值的插入位置,使得插入后数组仍然有序。
- 题目中提到学号是唯一的,因此不存在重复学号问题。
- 二分查找:
- 二分查找是一种在有序数组中查找目标值的高效算法,时间复杂度为O(log n)。
- 二分查找的基本思想是将数组分为两半,通过比较目标值与中间值的大小,确定目标值可能存在的区间,然后在该区间内继续查找,直到找到目标值或确定目标值的插入位置。
- 查找插入位置:
- 初始化两个指针
left
和right
,分别指向数组的起始位置和结束位置。 - 在
left
小于等于right
的条件下,进行循环:- 计算中间位置
mid
。 - 如果目标值等于
mid
位置的值,则返回mid
。 - 如果目标值小于
mid
位置的值,则将right
指针移动到mid - 1
。 - 如果目标值大于
mid
位置的值,则将left
指针移动到mid + 1
。
- 计算中间位置
- 当循环结束时,
left
指针的位置即为目标值的插入位置。
- 初始化两个指针
- 输出结果:
- 输出
left + 1
,因为队列位置从1开始。
- 输出
注意事项
- 边界条件:确保在处理边界条件时,指针的移动是正确的,避免死循环。
- 插入位置:当目标值不在数组中时,
left
指针的位置即为目标值的插入位置。 - 效率:二分查找的时间复杂度为O(log n),满足题目要求的算法复杂度不高于nLog(n)。
二、JavaScript算法源码
以下是 JavaScript 代码的详细中文注释和讲解:
JavaScript 代码
// 引入 readline 模块,用于从控制台读取输入
const rl = require("readline").createInterface({ input: process.stdin });// 获取异步迭代器
var iter = rl[Symbol.asyncIterator]();// 定义异步函数 readline,用于读取一行输入
const readline = async () => (await iter.next()).value;// 立即执行异步函数
void (async function () {// 读取第一行输入,按逗号分割并转换为数字数组const nums = (await readline()).split(",").map(Number);// 读取第二行输入,转换为目标值const target = parseInt(await readline());// 调用二分查找函数,查找目标值的位置let idx = binarySearch(nums, target);// 如果目标值不存在,计算其有序插入位置if (idx < 0) {idx = -idx - 1;}// 输出队列位置(从1开始),因此索引+1console.log(idx + 1);
})();// 二分查找函数,参照 Java 的 Arrays.binarySearch 实现
function binarySearch(nums, target) {let low = 0; // 查找范围的左边界let high = nums.length - 1; // 查找范围的右边界// 当左边界小于等于右边界时,继续查找while (low <= high) {// 计算中间位置const mid = (low + high) >> 1; // 等价于 Math.floor((low + high) / 2)const midVal = nums[mid]; // 中间位置的值// 如果中间值大于目标值,缩小查找范围到左半部分if (midVal > target) {high = mid - 1;}// 如果中间值小于目标值,缩小查找范围到右半部分else if (midVal < target) {low = mid + 1;}// 如果中间值等于目标值,返回目标值的位置else {return mid;}}// 如果目标值不存在,返回其有序插入位置的负数形式return -low - 1;
}
详细讲解
1. 输入获取
const rl = require("readline").createInterface({ input: process.stdin });var iter = rl[Symbol.asyncIterator]();const readline = async () => (await iter.next()).value;
- 功能:
- 使用
readline
模块从控制台读取输入。 - 通过异步迭代器逐行读取输入。
- 使用
- 说明:
rl[Symbol.asyncIterator]()
获取异步迭代器。readline
函数每次调用会返回一行输入。
2. 主逻辑
void (async function () {// 读取第一行输入,按逗号分割并转换为数字数组const nums = (await readline()).split(",").map(Number);// 读取第二行输入,转换为目标值const target = parseInt(await readline());// 调用二分查找函数,查找目标值的位置let idx = binarySearch(nums, target);// 如果目标值不存在,计算其有序插入位置if (idx < 0) {idx = -idx - 1;}// 输出队列位置(从1开始),因此索引+1console.log(idx + 1);
})();
- 功能:
- 读取输入并解析为数字数组和目标值。
- 调用二分查找函数查找目标值的位置。
- 如果目标值不存在,计算其有序插入位置。
- 输出目标值在数组中的位置(从 1 开始计数)。
- 说明:
split(",")
按逗号分割字符串。map(Number)
将字符串数组转换为数字数组。parseInt
将目标值转换为整数。
3. 二分查找函数
function binarySearch(nums, target) {let low = 0; // 查找范围的左边界let high = nums.length - 1; // 查找范围的右边界// 当左边界小于等于右边界时,继续查找while (low <= high) {// 计算中间位置const mid = (low + high) >> 1; // 等价于 Math.floor((low + high) / 2)const midVal = nums[mid]; // 中间位置的值// 如果中间值大于目标值,缩小查找范围到左半部分if (midVal > target) {high = mid - 1;}// 如果中间值小于目标值,缩小查找范围到右半部分else if (midVal < target) {low = mid + 1;}// 如果中间值等于目标值,返回目标值的位置else {return mid;}}// 如果目标值不存在,返回其有序插入位置的负数形式return -low - 1;
}
- 功能:
- 在有序数组
nums
中查找目标值target
。 - 如果找到目标值,返回其索引。
- 如果未找到目标值,返回其有序插入位置的负数形式。
- 在有序数组
- 说明:
low
和high
分别表示查找范围的左右边界。mid
是中间位置的索引。>> 1
是位运算,等价于除以 2 并向下取整。- 如果目标值不存在,
low
是其有序插入位置。
代码运行示例
示例 1:
输入:
1,3,5,7,9
5
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值5
的索引为2
。 - 队列位置从 1 开始计数,因此输出
3
。
示例 2:
输入:
1,3,5,7,9
4
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值4
不存在。 - 其有序插入位置为
2
(插入后数组为[1, 3, 4, 5, 7, 9]
)。 - 队列位置从 1 开始计数,因此输出
3
。
总结
-
功能:
- 在有序数组中查找目标值的位置。
- 如果目标值不存在,计算其有序插入位置。
-
优点:
- 使用二分查找,时间复杂度为
O(log n)
,效率高。 - 代码逻辑清晰,易于理解。
- 使用二分查找,时间复杂度为
-
适用场景:
- 适用于需要快速查找或插入位置的场景。
如果您有其他问题,欢迎随时提问!
三、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);// 读取第一行输入,按逗号分割并转换为整数数组int[] nums = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();// 读取第二行输入,转换为目标值int target = Integer.parseInt(sc.nextLine());// 使用 Arrays.binarySearch 查找目标值的位置// 如果目标值不存在,返回其有序插入位置的负数形式int idx = Arrays.binarySearch(nums, target);// 如果目标值不存在,计算其有序插入位置if (idx < 0) {idx = -idx - 1;}// 输出队列位置(从1开始),因此索引+1System.out.println(idx + 1);}
}
详细讲解
1. 输入获取
Scanner sc = new Scanner(System.in);
- 功能:
- 创建
Scanner
对象,用于从控制台读取输入。
- 创建
- 说明:
Scanner
是 Java 中常用的输入工具类。
2. 解析输入
int[] nums = Arrays.stream(sc.nextLine().split(",")).mapToInt(Integer::parseInt).toArray();
- 功能:
- 读取第一行输入,按逗号分割并转换为整数数组。
- 说明:
sc.nextLine()
读取一行输入。split(",")
按逗号分割字符串。Arrays.stream()
将字符串数组转换为流。mapToInt(Integer::parseInt)
将字符串流转换为整数流。toArray()
将流转换为整数数组。
3. 读取目标值
int target = Integer.parseInt(sc.nextLine());
- 功能:
- 读取第二行输入,转换为目标值。
- 说明:
sc.nextLine()
读取一行输入。Integer.parseInt()
将字符串转换为整数。
4. 二分查找
int idx = Arrays.binarySearch(nums, target);
- 功能:
- 使用
Arrays.binarySearch
在有序数组nums
中查找目标值target
。
- 使用
- 说明:
- 如果找到目标值,返回其索引。
- 如果未找到目标值,返回其有序插入位置的负数形式(
-low - 1
)。
5. 处理查找结果
if (idx < 0) {idx = -idx - 1;
}
- 功能:
- 如果目标值不存在,计算其有序插入位置。
- 说明:
Arrays.binarySearch
返回负数时,表示目标值不存在。-idx - 1
是目标值的有序插入位置。
6. 输出结果
System.out.println(idx + 1);
- 功能:
- 输出目标值在数组中的位置(从 1 开始计数)。
- 说明:
idx + 1
将索引转换为队列位置。
代码运行示例
示例 1:
输入:
1,3,5,7,9
5
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值5
的索引为2
。 - 队列位置从 1 开始计数,因此输出
3
。
示例 2:
输入:
1,3,5,7,9
4
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值4
不存在。 - 其有序插入位置为
2
(插入后数组为[1, 3, 4, 5, 7, 9]
)。 - 队列位置从 1 开始计数,因此输出
3
。
总结
-
功能:
- 在有序数组中查找目标值的位置。
- 如果目标值不存在,计算其有序插入位置。
-
优点:
- 使用
Arrays.binarySearch
,时间复杂度为O(log n)
,效率高。 - 代码简洁,逻辑清晰。
- 使用
-
适用场景:
- 适用于需要快速查找或插入位置的场景。
如果您有其他问题,欢迎随时提问!
四、Python算法源码
以下是 Python 代码的详细中文注释和讲解:
Python 代码
# 输入获取
nums = list(map(int, input().split(","))) # 读取输入并转换为整数列表
target = int(input()) # 读取目标值# 算法入口
def binarySearch():# 参照 Java 的 Arrays.binarySearch 实现low = 0 # 查找范围的左边界high = len(nums) - 1 # 查找范围的右边界while low <= high:mid = (low + high) >> 1 # 计算中间位置,等价于 (low + high) // 2midVal = nums[mid] # 中间位置的值if midVal > target:high = mid - 1 # 如果中间值大于目标值,缩小查找范围到左半部分elif midVal < target:low = mid + 1 # 如果中间值小于目标值,缩小查找范围到右半部分else:return mid # 如果中间值等于目标值,返回目标值的位置return -low - 1 # 如果目标值不存在,返回其有序插入位置的负数形式# 算法调用
idx = binarySearch()# 如果目标值不存在,计算其有序插入位置
if idx < 0:idx = -idx - 1# 输出队列位置(从1开始),因此索引+1
print(idx + 1)
详细讲解
1. 输入获取
nums = list(map(int, input().split(","))) # 读取输入并转换为整数列表
target = int(input()) # 读取目标值
- 功能:
- 从控制台读取输入,并将其转换为整数列表和目标值。
- 说明:
input()
读取一行输入。split(",")
按逗号分割字符串。map(int, ...)
将字符串列表转换为整数列表。list(...)
将映射结果转换为列表。
2. 二分查找算法
def binarySearch():low = 0 # 查找范围的左边界high = len(nums) - 1 # 查找范围的右边界while low <= high:mid = (low + high) >> 1 # 计算中间位置,等价于 (low + high) // 2midVal = nums[mid] # 中间位置的值if midVal > target:high = mid - 1 # 如果中间值大于目标值,缩小查找范围到左半部分elif midVal < target:low = mid + 1 # 如果中间值小于目标值,缩小查找范围到右半部分else:return mid # 如果中间值等于目标值,返回目标值的位置return -low - 1 # 如果目标值不存在,返回其有序插入位置的负数形式
- 功能:
- 在有序数组
nums
中查找目标值target
。 - 如果找到目标值,返回其索引。
- 如果未找到目标值,返回其有序插入位置的负数形式。
- 在有序数组
- 说明:
low
和high
分别表示查找范围的左右边界。mid
是中间位置的索引。>> 1
是位运算,等价于除以 2 并向下取整。- 如果目标值不存在,
low
是其有序插入位置。
3. 处理查找结果
idx = binarySearch()if idx < 0:idx = -idx - 1
- 功能:
- 如果目标值不存在,计算其有序插入位置。
- 说明:
binarySearch
返回负数时,表示目标值不存在。-idx - 1
是目标值的有序插入位置。
4. 输出结果
print(idx + 1)
- 功能:
- 输出目标值在数组中的位置(从 1 开始计数)。
- 说明:
idx + 1
将索引转换为队列位置。
代码运行示例
示例 1:
输入:
1,3,5,7,9
5
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值5
的索引为2
。 - 队列位置从 1 开始计数,因此输出
3
。
示例 2:
输入:
1,3,5,7,9
4
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值4
不存在。 - 其有序插入位置为
2
(插入后数组为[1, 3, 4, 5, 7, 9]
)。 - 队列位置从 1 开始计数,因此输出
3
。
总结
-
功能:
- 在有序数组中查找目标值的位置。
- 如果目标值不存在,计算其有序插入位置。
-
优点:
- 使用二分查找,时间复杂度为
O(log n)
,效率高。 - 代码简洁,逻辑清晰。
- 使用二分查找,时间复杂度为
-
适用场景:
- 适用于需要快速查找或插入位置的场景。
如果您有其他问题,欢迎随时提问!
五、C/C++算法源码:
以下是 C语言 和 C++ 代码的详细中文注释和讲解:
C语言代码
#include <stdio.h>#define MAX_SIZE 10000 // 定义数组的最大长度// 二分查找函数,参照 Java 的 Arrays.binarySearch 实现
int binarySearch(const int *nums, int nums_size, int target) {int low = 0; // 查找范围的左边界int high = nums_size - 1; // 查找范围的右边界while (low <= high) {int mid = (low + high) >> 1; // 计算中间位置,等价于 (low + high) / 2int midVal = nums[mid]; // 中间位置的值if (midVal > target) {high = mid - 1; // 如果中间值大于目标值,缩小查找范围到左半部分} else if (midVal < target) {low = mid + 1; // 如果中间值小于目标值,缩小查找范围到右半部分} else {return mid; // 如果中间值等于目标值,返回目标值的位置}}return -low - 1; // 如果目标值不存在,返回其有序插入位置的负数形式
}int main() {int nums[MAX_SIZE]; // 定义数组int nums_size = 0; // 数组的当前长度// 读取输入,按逗号分割并存储到数组中while (scanf("%d", &nums[nums_size++])) {if (getchar() != ',') break; // 如果下一个字符不是逗号,结束输入}int target; // 定义目标值scanf("%d", &target); // 读取目标值// 调用二分查找函数,查找目标值的位置int idx = binarySearch(nums, nums_size, target);// 如果目标值不存在,计算其有序插入位置if (idx < 0) {idx = -idx - 1;}// 输出队列位置(从1开始),因此索引+1printf("%d\n", idx + 1);return 0;
}
C++代码
#include <iostream>
#include <vector>
using namespace std;// 二分查找函数,参照 Java 的 Arrays.binarySearch 实现
int binarySearch(const vector<int>& nums, int target) {int low = 0; // 查找范围的左边界int high = nums.size() - 1; // 查找范围的右边界while (low <= high) {int mid = (low + high) >> 1; // 计算中间位置,等价于 (low + high) / 2int midVal = nums[mid]; // 中间位置的值if (midVal > target) {high = mid - 1; // 如果中间值大于目标值,缩小查找范围到左半部分} else if (midVal < target) {low = mid + 1; // 如果中间值小于目标值,缩小查找范围到右半部分} else {return mid; // 如果中间值等于目标值,返回目标值的位置}}return -low - 1; // 如果目标值不存在,返回其有序插入位置的负数形式
}int main() {vector<int> nums; // 定义动态数组int num;char sep;// 读取输入,按逗号分割并存储到数组中while (cin >> num) {nums.push_back(num);sep = cin.get(); // 读取分隔符if (sep != ',') break; // 如果下一个字符不是逗号,结束输入}int target; // 定义目标值cin >> target; // 读取目标值// 调用二分查找函数,查找目标值的位置int idx = binarySearch(nums, target);// 如果目标值不存在,计算其有序插入位置if (idx < 0) {idx = -idx - 1;}// 输出队列位置(从1开始),因此索引+1cout << idx + 1 << endl;return 0;
}
详细讲解
1. 输入获取
-
C语言:
while (scanf("%d", &nums[nums_size++])) {if (getchar() != ',') break; }
- 使用
scanf
读取整数,getchar
读取分隔符。 - 如果分隔符不是逗号,结束输入。
- 使用
-
C++:
while (cin >> num) {nums.push_back(num);sep = cin.get();if (sep != ',') break; }
- 使用
cin
读取整数,cin.get
读取分隔符。 - 如果分隔符不是逗号,结束输入。
- 使用
2. 二分查找算法
int binarySearch(const int *nums, int nums_size, int target) {int low = 0;int high = nums_size - 1;while (low <= high) {int mid = (low + high) >> 1;int midVal = nums[mid];if (midVal > target) {high = mid - 1;} else if (midVal < target) {low = mid + 1;} else {return mid;}}return -low - 1;
}
- 功能:
- 在有序数组
nums
中查找目标值target
。 - 如果找到目标值,返回其索引。
- 如果未找到目标值,返回其有序插入位置的负数形式。
- 在有序数组
- 说明:
low
和high
分别表示查找范围的左右边界。mid
是中间位置的索引。>> 1
是位运算,等价于除以 2 并向下取整。- 如果目标值不存在,
low
是其有序插入位置。
3. 处理查找结果
if (idx < 0) {idx = -idx - 1;
}
- 功能:
- 如果目标值不存在,计算其有序插入位置。
- 说明:
binarySearch
返回负数时,表示目标值不存在。-idx - 1
是目标值的有序插入位置。
4. 输出结果
printf("%d\n", idx + 1);
- 功能:
- 输出目标值在数组中的位置(从 1 开始计数)。
- 说明:
idx + 1
将索引转换为队列位置。
代码运行示例
示例 1:
输入:
1,3,5,7,9
5
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值5
的索引为2
。 - 队列位置从 1 开始计数,因此输出
3
。
示例 2:
输入:
1,3,5,7,9
4
输出:
3
解释:
- 数组
[1, 3, 5, 7, 9]
中,目标值4
不存在。 - 其有序插入位置为
2
(插入后数组为[1, 3, 4, 5, 7, 9]
)。 - 队列位置从 1 开始计数,因此输出
3
。
总结
-
功能:
- 在有序数组中查找目标值的位置。
- 如果目标值不存在,计算其有序插入位置。
-
优点:
- 使用二分查找,时间复杂度为
O(log n)
,效率高。 - 代码简洁,逻辑清晰。
- 使用二分查找,时间复杂度为
-
适用场景:
- 适用于需要快速查找或插入位置的场景。
如果您有其他问题,欢迎随时提问!
六、尾言
什么是华为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 或监考人员进行反馈。
祝你考试顺利,取得理想成绩!