自学内容网 自学内容网

华为OD机试 - 分班问题(Python/JS/C/C++ 2024 E卷 200分)

在这里插入图片描述

华为OD机试 2024E卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新,全天CSDN在线答疑。

一、题目描述

幼儿园两个班的同小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班,请你帮忙把同班的小朋友找出来。
小朋友的编号是整数,与前一位小朋友同班用Y表示,不同班用N表示。
学生序号范围[0,999],如果输入不合法则打印ERROR。

二、输入描述

输入为空格分开的朋友编号和是否同班标志。

三、输出描述

输出为两行,每一行记录一个班小朋友的编号,编号用空格分开,且:

  1. 编号需要按升序排列。
  2. 若只有一个班的小朋友,第二行为空行。

四、测试用例

测试用例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。

五、解题思路

  1. 输入处理与验证:
    • 将输入字符串按空格分割成多个小朋友的记录。
    • 对每个记录进行验证,确保格式为编号/标志。
    • 检查编号是否为整数且在[0,999]范围内。
    • 检查标志是否为Y或N。
    • 若任何验证失败,输出ERROR并终止程序。
  2. 班级分配:
    • 初始化两个班级A和B。
    • 使用一个变量currentClass跟踪当前班级,0表示班级A,1表示班级B。
    • 对于第一个小朋友,标志必须为N,分配到班级A。
  3. 对于后续的小朋友:
    • 若标志为Y,分配到与前一个小朋友相同的班级。
    • 若标志为N,切换到另一个班级分配。
  4. 排序与输出:
    • 对班级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在线答疑。

在这里插入图片描述


原文地址:https://blog.csdn.net/guorui_java/article/details/142691020

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!