华为OD机考的双机位C卷里,测试用例执行计划这道题最近出现的频率相当高,Java、Python、JS、GO、C++、C这六种语言在考场里都有人选。题目本身不复杂,核心就是一个带优先级的排序问题:按测试用例优先级从高到低排,优先级相同再按编号从小到大排。但越是这种基础题,越容易在输入输出处理、比较器写法、多组输入这几件事上翻车,我见过不少人在“送分题”上因为一个小细节丢分,非常可惜。
这篇内容就把这道题从题目原型、六种语言实现、排序原理到踩坑点全部展开,适合正在准备华为OD机考的同学,也适合想练ACM模式排序题的人。无论你主力语言是Java还是Python,或者打算用JS/C++/GO/C,这篇都能直接抄作业。我尽量把代码写完整,把“为什么这么写”也讲透,而不是只贴一段能过样例的代码就完事。
1. 题目拆解:C卷里这道题到底在考什么
1.1 华为OD机考C卷的出题特征
华为OD机考不是传统意义上的性格测试或者行测,它考的是纯算法上机,用ACM模式写代码,就是自己处理标准输入输出,而不是像力扣那样直接实现一个函数。C卷是最近一个批次的题目集合,整体难度分布比较稳定,通常有三道题,第一题偏简单,第二题偏排序和字符串处理,第三题偏动态规划和贪心。测试用例执行计划这种题就经常出现在第二题的位置,属于“拉开分数差距前必须先拿稳”的那一类。
从通过率数据来看,这类题其实卡住不少人的地方反而不在排序逻辑,而在三点:一是没有处理多组输入,二是比较器写反了方向,三是自测没问题但提交后格式不对。所以后面我会花不少篇幅讲输入输出和格式细节,这部分才是真正的实战经验。
1.2 测试用例执行计划的题目原型
题目描述大概是这样:在软件测试中,每天只能执行一个测试用例,现在有n个测试用例,编号从1到n,每个用例有一个优先级。需要按照优先级从高到低确定执行顺序,如果两个用例优先级相同,则编号小的先执行。输入第一行给n,第二行给n个整数表示每个用例的优先级,输出一行,是排好的用例编号顺序,用空格分隔。
举个例子,输入:
code复制5
1 3 3 2 5
这里5个用例的优先级分别是1、3、3、2、5,按优先级降序排,编号5的优先级5最大排第一,编号2和3的优先级都是3,编号2更小所以排前面,接着是编号4优先级2,最后是编号1优先级1,输出就是:
code复制5 2 3 4 1
这个例子我建议你在看任何语言的代码之前先自己手推一遍,把“排序键是什么”搞清楚。排序是先看优先级,再看编号,而且两个方向不一样,优先级是降序,编号是升序。这就是所谓多关键字排序,也是这道题唯一的算法考点。
1.3 双机位监考环境下的答题策略
双机位意味着考试时一个摄像头对着你,另一个手机放在侧后方监控你的屏幕和操作,全程不能切屏、不能查资料、不能打开本地笔记。这意味着平时不背模板的话,考场现想IO代码会非常痛苦。尤其是JS的readline、GO的bufio.Scanner、C的qsort比较函数,这些如果不熟,思路再清晰也会卡在环境搭建上。
我建议的策略是:主攻两门语言,一门用于稳过,一门用于备用。比如Java主力,Python查缺补漏。剩下四种语言至少要能看懂、能讲清思路,因为万一抽到的题目你熟悉的语言有某个边界问题,换语言写反而更快。后面给六种语言代码,也是为了方便你在考场上“哪里不会切哪里”。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 六种语言实现方案与核心代码
2.1 Java:Comparator比较器实现
Java在OD机考里的出场率一直很高,主要是因为很多人的第一语言就是Java,而且Java的集合类写排序很顺手。这道题的关键是定义TestCase类,然后用Collections.sort加自定义比较器。
java复制import java.util.*;
import java.io.*;
public class Main {
static class TestCase {
int id;
int priority;
TestCase(int id, int priority) {
this.id = id;
this.priority = priority;
}
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line;
while ((line = br.readLine()) != null) {
int n = Integer.parseInt(line.trim());
String[] parts = br.readLine().trim().split(" ");
List<TestCase> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
list.add(new TestCase(i + 1, Integer.parseInt(parts[i])));
