华为OD机试 2024E卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/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的编号分别进行升序排序。
- 按要求格式输出两个班级的编号,若某一班级为空,输出空行。
六、Python算法源码
import sys
def find_classes(records):
"""
根据小朋友的记录,分配到两个班级
:param records: list of tuples (number, flag)
:return: 两个班级的列表
"""
classA = []
classB = []
current_class = -1 # 0表示班级A,1表示班级B
for i, (number, flag) in enumerate(records):
if i == 0:
# 第一个小朋友,标志必须是'N',分配到班级A
if flag != 'N':
return "ERROR", None
current_class = 0 # 班级A
classA.append(number)
else:
if flag == 'Y':
# 与前一个小朋友同班
if current_class == 0:
classA.append(number)
else:
classB.append(number)
elif flag == 'N':
# 与前一个小朋友不同班
current_class = 1 - current_class # 切换班级
if current_class == 0:
classA.append(number)
else:
classB.append(number)
else:
# 非法标志
return "ERROR", None
return classA, classB
def main():
input_line = sys.stdin.readline().strip()
if not input_line:
print("ERROR")
return
tokens = input_line.split()
records = []
for token in tokens:
if '/' not in token:
print("ERROR")
return
parts = token.split('/')
if len(parts) != 2:
print("ERROR")
return
number_str, flag = parts
try:
number = int(number_str)
except ValueError:
print("ERROR")
return
if not (0 <= number <= 999):
print("ERROR")
return
if flag not in ('Y', 'N'):
print("ERROR")
return
records.append((number, flag))
classA, classB = find_classes(records)
if classA == "ERROR":
print("ERROR")
return
# 排序
classA_sorted = sorted(classA)
classB_sorted = sorted(classB)
# 输出
print(' '.join(map(str, classA_sorted)))
print(' '.join(map(str, classB_sorted)))
if __name__ == "__main__":
main()
七、JavaScript算法源码
// 导入readline模块用于读取输入
const readline = require('readline');
// 创建接口以读取输入
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
let input = []; // 用于存储输入的行
// 监听每一行输入
rl.on('line', (line) => {
input.push(line.trim());
// 假设输入只有一行,如果需要多行,可以调整条件
// 根据题目描述,输入是一个行的记录
if (input.length === 1) {
processInput(input[0]);
rl.close(); // 关闭输入流
}
});
/**
* 处理输入并分配班级
* @param {string} inputLine 输入的字符串
*/
function processInput(inputLine) {
if (!inputLine) {
console.log("ERROR");
console.log("");
return;
}
// 分割输入为每个小朋友的记录
const tokens = inputLine.split(' ');
let classA = [];
let classB = [];
let currentClass = -1; // 0表示班级A,1表示班级B
for (let i = 0; i < tokens.length; i++) {
let token = tokens[i];
// 检查是否包含'/'
if (!token.includes('/')) {
console.log("ERROR");
return;
}
// 分割编号和标志
let parts = token.split('/');
if (parts.length !== 2) {
console.log("ERROR");
return;
}
let numberStr = parts[0].trim();
let flag = parts[1].trim();
// 检查编号是否为整数
let number = parseInt(numberStr, 10);
if (isNaN(number)) {
console.log("ERROR");
return;
}
// 检查编号是否在[0,999]范围内
if (number < 0 || number > 999) {
console.log("ERROR");
return;
}
// 检查标志是否为'Y'或'N'
if (flag !== 'Y' && flag !== 'N') {
console.log("ERROR");
return;
}
// 处理班级分配
if (i === 0) {
// 第一个小朋友,标志必须是'N',分配到班级A
if (flag !== 'N') {
console.log("ERROR");
return;
}
currentClass = 0; // 班级A
classA.push(number);
} else {
if (flag === 'Y') {
// 与前一个小朋友同班
if (currentClass === 0) {
classA.push(number);
} else {
classB.push(number);
}
} else if (flag === 'N') {
// 与前一个小朋友不同班
currentClass = 1 - currentClass; // 切换班级
if (currentClass === 0) {
classA.push(number);
} else {
classB.push(number);
}
}
}
}
// 排序
classA.sort((a, b) => a - b);
classB.sort((a, b) => a - b);
// 构建输出字符串
let outputA = classA.join(' ');
let outputB = classB.join(' ');
// 输出两个班级的编号
console.log(outputA);
console.log(outputB);
}
八、C算法源码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// 定义最大商品数量和最大价格
#define MAX_ITEMS 1000
int main() {
char inputLine[5000];
// 读取整行输入
if (fgets(inputLine, sizeof(inputLine), stdin) == NULL) {
printf("ERROR\n");
return 0;
}
// 去除换行符
size_t len = strlen(inputLine);
if (len > 0 && inputLine[len - 1] == '\n') {
inputLine[len - 1] = '\0';
}
// 分割输入为每个小朋友的记录
char *token = strtok(inputLine, " ");
if (token == NULL) {
printf("ERROR\n");
return 0;
}
int classA[MAX_ITEMS];
int classB[MAX_ITEMS];
int countA = 0, countB = 0;
int currentClass = -1; // 0表示班级A,1表示班级B
int index = 0;
while (token != NULL) {
// 检查是否包含'/'
char *slash = strchr(token, '/');
if (slash == NULL) {
printf("ERROR\n");
return 0;
}
// 分割编号和标志
*slash = '\0';
char *numberStr = token;
char *flag = slash + 1;
// 检查标志是否为'Y'或'N'
if (strcmp(flag, "Y") != 0 && strcmp(flag, "N") != 0) {
printf("ERROR\n");
return 0;
}
// 检查编号是否为整数
char *endptr;
long numberLong = strtol(numberStr, &endptr, 10);
if (*endptr != '\0') {
printf("ERROR\n");
return 0;
}
int number = (int)numberLong;
// 检查编号是否在[0,999]范围内
if (number < 0 || number > 999) {
printf("ERROR\n");
return 0;
}
// 处理班级分配
if (index == 0) {
// 第一个小朋友,标志必须是'N',分配到班级A
if (strcmp(flag, "N") != 0) {
printf("ERROR\n");
return 0;
}
currentClass = 0; // 班级A
classA[countA++] = number;
} else {
if (strcmp(flag, "Y") == 0) {
// 与前一个小朋友同班
if (currentClass == 0) {
classA[countA++] = number;
} else {
classB[countB++] = number;
}
} else if (strcmp(flag, "N") == 0) {
// 与前一个小朋友不同班
currentClass = 1 - currentClass; // 切换班级
if (currentClass == 0) {
classA[countA++] = number;
} else {
classB[countB++] = number;
}
}
}
index++;
token = strtok(NULL, " ");
}
// 排序班级A
for (int i = 0; i < countA - 1; i++) {
for (int j = i + 1; j < countA; j++) {
if (classA[i] > classA[j]) {
int temp = classA[i];
classA[i] = classA[j];
classA[j] = temp;
}
}
}
// 排序班级B
for (int i = 0; i < countB - 1; i++) {
for (int j = i + 1; j < countB; j++) {
if (classB[i] > classB[j]) {
int temp = classB[i];
classB[i] = classB[j];
classB[j] = temp;
}
}
}
// 输出班级A
for (int i = 0; i < countA; i++) {
printf("%d", classA[i]);
if (i != countA - 1) {
printf(" ");
}
}
printf("\n");
// 输出班级B
for (int i = 0; i < countB; i++) {
printf("%d", classB[i]);
if (i != countB - 1) {
printf(" ");
}
}
printf("\n");
return 0;
}
九、C++算法源码
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <string>
using namespace std;
int main(){
// 读取整行输入
string inputLine;
if(!getline(cin, inputLine)){
// 如果读取失败,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
// 去除前后空格
size_t start = inputLine.find_first_not_of(" ");
size_t end = inputLine.find_last_not_of(" ");
if(start == string::npos){
// 输入全为空,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
inputLine = inputLine.substr(start, end - start +1);
// 分割输入为每个小朋友的记录
vector<string> tokens;
stringstream ss(inputLine);
string token;
while(ss >> token){
tokens.push_back(token);
}
// 初始化两个班级的列表
vector<int> classA;
vector<int> classB();
// 当前班级标志,0表示班级A,1表示班级B
int currentClass = -1;
// 遍历每个小朋友的记录
for(int i=0; i<tokens.size(); i++){
string t = tokens[i];
// 检查是否包含'/'
size_t slashPos = t.find('/');
if(slashPos == string::npos){
// 如果不包含'/',输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
// 分割编号和标志
string numberStr = t.substr(0, slashPos);
string flag = t.substr(slashPos+1);
// 去除可能的空格
size_t numStart = numberStr.find_first_not_of(" ");
size_t numEnd = numberStr.find_last_not_of(" ");
if(numStart == string::npos){
// 编号为空,输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
numberStr = numberStr.substr(numStart, numEnd - numStart +1);
size_t flagStart = flag.find_first_not_of(" ");
size_t flagEnd = flag.find_last_not_of(" ");
if(flagStart == string::npos){
// 标志为空,输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
flag = flag.substr(flagStart, flagEnd - flagStart +1);
// 检查编号是否为整数
int number;
try{
number = stoi(numberStr);
}
catch(...){
// 编号不是有效整数,输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
// 检查编号是否在[0,999]范围内
if(number <0 || number >999){
// 编号超出范围,输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
// 检查标志是否为'Y'或'N'
if(flag != "Y" && flag != "N"){
// 标志不是'Y'或'N',输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
// 处理班级分配
if(i ==0){
// 第一个小朋友,标志必须为'N'
if(flag != "N"){
// 第一个小朋友标志不是'N',输入不合法,输出ERROR并结束程序
cout << "ERROR" << endl;
return 0;
}
currentClass =0; // 班级A
classA.push_back(number);
}
else{
if(flag == "Y"){
// 与前一个小朋友同班
if(currentClass ==0){
classA.push_back(number);
}
else{
classB.push_back(number);
}
}
else{
// 与前一个小朋友不同班,切换班级
currentClass =1 - currentClass;
if(currentClass ==0){
classA.push_back(number);
}
else{
classB.push_back(number);
}
}
}
}
// 对两个班级的编号进行升序排序
sort(classA.begin(), classA.end());
sort(classB.begin(), classB.end());
// 构建输出字符串
string outputA = "";
for(auto num : classA){
outputA += to_string(num) + " ";
}
if(outputA.length()>0){
outputA.pop_back(); // 移除最后一个空格
}
string outputB = "";
for(auto num : classB){
outputB += to_string(num) + " ";
}
if(outputB.length()>0){
outputB.pop_back(); // 移除最后一个空格
}
// 输出两个班级的编号
cout << outputA << endl;
cout << outputB << endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2024 E卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。