分班 - 华为OD统一考试(E卷)
2024华为OD机试(E卷+D卷+C卷)最新题库【超值优惠】Java/Python/C++合集
题目描述
幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友是否同班,请你帮忙把同班的小朋友找出来。
小朋友的编号为整数,与前一位小朋友同班用Y表示,不同班用N表示。
输入描述
输入为空格分开的小朋友编号和是否同班标志。
比如:6/N 2/Y 3/N 4/Y,表示共4位小朋友,2和6同班,3和2不同班,4和3同班。
其中,小朋友总数不超过999,每个小朋友编号大于0,小于等于999。
不考虑输入格式错误问题。
输出描述
输出为两行,每一行记录一个班小朋友的编号,编号用空格分开。且:
1、编号需要按照大小升序排列,分班记录中第一个编号小的排在第一行。
2、若只有一个班的小朋友,第二行为空行。
3、若输入不符合要求,则直接输出字符串ERROR。
示例1
输入:
1/N 2/Y 3/N 4/Y输出:
1 2
3 4说明:
2的同班标记为Y,因此和1同班。
3的同班标记为N,因此和1、2不同班。
4的同班标记为Y,因此和3同班。
所以1、2同班,3、4同班,输出为
1 2
3 4
题解
该题目属于贪心算法,也可以归类为字符串处理和数组操作类型的题目。通过对输入进行解析并根据条件将小朋友分班,需要保持结果的升序排列,同时处理异常输入。
解题思路
数据解析:输入是以空格分开的小朋友编号和是否同班标志。解析时要把小朋友编号与是否同班的标志分离开。
分班:从第一个小朋友开始,使用两个列表分别存放两个班的小朋友。根据标志 Y 或 N
判断当前小朋友应该分到哪个班:
- 如果标志是
Y
,那么当前小朋友与前一个小朋友同班。
- 如果标志是
N
,则当前小朋友与前一个小朋友不同班。
排序与输出:对于每个班的小朋友的编号,按照升序排列。并根据题目要求输出结果:
- 若两个班的小朋友编号都不为空,按照第一个编号较小的班级先输出。
- 若只有一个班的小朋友,则第二行输出空行。
- 异常处理:如果小朋友编号不在范围内,直接输出
ERROR
。
Java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;/*** @author code5bug*/
public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);String line = sc.nextLine();boolean err = false; // 输入是否不符合要求boolean one = true; // 当前的学生是否属于第一个班List<Integer> class1 = new ArrayList<>(); // 第一个班级的小朋友编号List<Integer> class2 = new ArrayList<>(); // 第二个班级的小朋友编号for (String p : line.split(" ")) {int idx = p.indexOf("/");int no = Integer.parseInt(p.substring(0, idx));char flag = p.charAt(idx + 1);// 输入不符合要求if (no < 0 || no > 999) err = true;if (flag == 'N') one = !one;if (one) class1.add(no);else class2.add(no);}if (err) {System.out.println("ERROR");} else {// 编号大小升序class1.sort(Comparator.comparingInt(o -> o));class2.sort(Comparator.comparingInt(o -> o));// 确保: 第一个编号小的在第一行(1班), 若只有一个班第二行为空行if (class1.isEmpty() || (!class2.isEmpty() && class2.get(0) < class1.get(0))) {printList(class2);printList(class1);} else {printList(class1);printList(class2);}}}// 打印一个班级的数据public static void printList(List<Integer> list) {StringBuilder sb = new StringBuilder();for (int i = 0; i < list.size(); i++) {sb.append(list.get(i));if (i + 1 != list.size()) sb.append(" ");}System.out.println(sb.toString());}
}
Python
line = input()
class1, class2 = [], []
err, one = False, True
for p in line.split():no, flag = p.split('/')no = int(no)if no < 0 or no > 999:err = Trueif flag == 'N':one = not oneif one:class1.append(no)else:class2.append(no)if err:print('ERROR')
else:class1.sort()class2.sort()if class1 and class2 and class2[0] < class1[0]:print(' '.join(map(str, class2)))print(' '.join(map(str, class1)))else:print(' '.join(map(str, class1)))print(' '.join(map(str, class2)))
C++
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>using namespace std;void print(vector<int> &cls) {string s;int len = cls.size();for (int i = 0; i < len; i++) {s += to_string(cls[i]);if (i + 1 != len) s += ' ';}cout << s << endl;
}int main() {bool one = true;bool err = false;vector<int> class1, class2;char cs[20];while (~scanf("%s", cs)) {int no;char flag;sscanf(cs, "%d/%c", &no, &flag);if (no < 0 || no > 999) err = true;if (flag == 'N') one = !one;if (one) class1.push_back(no);else class2.push_back(no);}if (err) {cout << "ERROR" << endl;return 0;}sort(class1.begin(), class1.end());sort(class2.begin(), class2.end());// 确保: 第一个编号小的在第一行(1班), 若只有一个班第二行为空行if (!class1.empty() && !class2.empty() && class1.front() > class2.front()) {print(class2);print(class1);}else{print(class1);print(class2);}return 0;
}
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏