华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试(JAVA)真题(E卷+D卷+A卷+B卷+C卷)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。
一、题目描述
幼儿园两个班的同小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班,请你帮忙把同班的小朋友找出来。
小朋友的编号是整数,与前一位小朋友同班用Y表示,不同班用N表示。
学生序号范围[0,999],如果输入不合法则打印ERROR。
二、输入描述
输入为空格分开的朋友编号和是否同班标志。
三、输出描述
输出为两行,每一行记录一个班小朋友的编号,编号用空格分开,且:
- 编号需要按升序排列。
- 若只有一个班的小朋友,第二行为空行。
四、测试用例
测试用例1:
1、输入
1/N 2/Y 3/N 4/Y
2、输出
1 2
3 4
3、说明
第一个小朋友编号1,标志为N,分配到班级A。
第二个小朋友编号2,标志为Y,与前一个同班,分配到班级A。
第三个小朋友编号3,标志为N,与前一个不同班,分配到班级B。
第四个小朋友编号4,标志为Y,与前一个同班,分配到班级B。
测试用例2:
1、输入
1/N 2/Y 3/N 4/Y 5/Y
2、输出
1 2
3 4 5
3、说明
第五个小朋友编号5,标志为Y,与前一个同班,分配到班级B。
五、解题思路
- 输入处理与验证:
- 将输入字符串按空格分割成多个小朋友的记录。
- 对每个记录进行验证,确保格式为编号/标志。
- 检查编号是否为整数且在[0,999]范围内。
- 检查标志是否为Y或N。
- 若任何验证失败,输出ERROR并终止程序。
- 班级分配:
- 初始化两个班级A和B。
- 使用一个变量currentClass跟踪当前班级,0表示班级A,1表示班级B。
- 对于第一个小朋友,标志必须为N,分配到班级A。
- 对于后续的小朋友:
- 若标志为Y,分配到与前一个小朋友相同的班级。
- 若标志为N,切换到另一个班级分配。
- 排序与输出:
- 对班级A和班级B的编号分别进行升序排序。
- 按要求格式输出两个班级的编号,若某一班级为空,输出空行。
六、Java算法源码
public class OdTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 读取整行输入
if (!scanner.hasNextLine()) {
System.out.println("ERROR");
scanner.close();
return;
}
String inputLine = scanner.nextLine().trim();
scanner.close();
// 如果输入为空,输出ERROR
if (inputLine.isEmpty()) {
System.out.println("ERROR");
return;
}
// 分割输入为每个小朋友的记录
String[] tokens = inputLine.split(" ");
// 初始化两个班级的列表
ArrayList<Integer> classA = new ArrayList<>();
ArrayList<Integer> classB = new ArrayList<>();
// 当前班级标志,0表示班级A,1表示班级B
int currentClass = -1;
// 遍历每个小朋友的记录
for (int i = 0; i < tokens.length; i++) {
String token = tokens[i];
// 检查是否包含'/'
if (!token.contains("/")) {
System.out.println("ERROR");
return;
}
// 分割编号和标志
String[] parts = token.split("/");
if (parts.length != 2) {
System.out.println("ERROR");
return;
}
String numberStr = parts[0].trim();
String flag = parts[1].trim();
// 检查编号是否为整数
int number;
try {
number = Integer.parseInt(numberStr);
} catch (NumberFormatException e) {
System.out.println("ERROR");
return;
}
// 检查编号是否在[0,999]范围内
if (number < 0 || number > 999) {
System.out.println("ERROR");
return;
}
// 检查标志是否为'Y'或'N'
if (!flag.equals("Y") && !flag.equals("N")) {
System.out.println("ERROR");
return;
}
// 处理班级分配
if (i == 0) {
// 第一个小朋友,标志必须是'N',表示开始一个新班级
if (!flag.equals("N")) {
System.out.println("ERROR");
return;
}
currentClass = 0; // 班级A
classA.add(number);
} else {
if (flag.equals("Y")) {
// 与前一个小朋友同班
if (currentClass == 0) {
classA.add(number);
} else {
classB.add(number);
}
} else {
// 与前一个小朋友不同班
currentClass = 1 - currentClass; // 切换班级
if (currentClass == 0) {
classA.add(number);
} else {
classB.add(number);
}
}
}
}
// 对两个班级的编号进行升序排序
Collections.sort(classA);
Collections.sort(classB);
// 构建输出字符串
StringBuilder outputA = new StringBuilder();
for (int num : classA) {
outputA.append(num).append(" ");
}
// 移除最后一个空格
if (outputA.length() > 0) {
outputA.setLength(outputA.length() - 1);
}
StringBuilder outputB = new StringBuilder();
for (int num : classB) {
outputB.append(num).append(" ");
}
// 移除最后一个空格
if (outputB.length() > 0) {
outputB.setLength(outputB.length() - 1);
}
// 输出两个班级的编号
System.out.println(outputA.toString());
System.out.println(outputB.toString());
}
}
七、效果展示
1、输入
10/N 20/Y 30/Y 40/N 50/Y
2、输出
10 20 30
40 50
3、说明
小朋友10/N分配到班级A。
小朋友20/Y与10同班,分配到班级A。
小朋友30/Y与20同班,分配到班级A。
小朋友40/N与30不同班,分配到班级B。
小朋友50/Y与40同班,分配到班级B。
🏆下一篇:华为OD机试 - 简易内存池 - 逻辑分析(Java 2024 E卷 200分)
🏆本文收录于,华为OD机试(JAVA)真题(E卷+D卷+A卷+B卷+C卷)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。