华为OD机试题库《C++》限时优惠 9.9
华为OD机试题库《Python》限时优惠 9.9
华为OD机试题库《JavaScript》限时优惠 9.9
针对刷题难,效率慢,我们提供一对一算法辅导, 针对个人情况定制化的提高计划(全称1V1效率更高)。
看不懂有疑问需要答疑辅导欢迎私VX: code5bug
题目描述
幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友是否同班,请你帮忙把同班的小朋友找出来。
小朋友的编号为整数,与前一位小朋友同班用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
。
JavaScript
const rl = require('readline').createInterface({
input: process.stdin,
output: process.stdout,
});
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
// Author: code5bug
(async () => {
const input = (await readline()).split(' ').map((p) => {
let [num, flag] = p.split('/');
return [parseInt(num), flag];
});
// cls[2] 数组用于表示两个班级
const cls = Array(2)
.fill()
.map(() => []);
// 前一个同学所在的班级,输入是否不合法
let pre = 0,
err = false;
input.forEach(([num, flag]) => {
let idx = flag === 'Y' ? pre : pre ^ 1;
cls[idx].push(num);
// 输入不合法
if (num <= 0 || num > 999) err = true;
pre = idx;
});
if (err) {
console.log('ERROR');
} else {
// 对每个班级的学生编号升序排序
cls.forEach((arr) => arr.sort());
let r1 = cls[0].join(' ');
let r2 = cls[1].join(' ');
// 编号需要按照大小升序排列,分班记录中第一个编号小的排在第一行
if (r1.localeCompare(r2) > 0) {
[r1, r2] = [r2, r1];
}
// 打印结果
console.log(r1);
console.log(r2);
}
rl.close();
})();
整理题解不易, 如果有帮助到您,请给点个赞 ❤️ 和收藏 ⭐,让更多的人看到。🙏🙏🙏