分班 - 华为OD统一考试(E卷)

2024华为OD机试(E卷+D卷+C卷)最新题库【超值优惠】Java/Python/C++合集

华为od机试

题目描述

幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友是否同班,请你帮忙把同班的小朋友找出来。

小朋友的编号为整数,与前一位小朋友同班用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

题解

该题目属于贪心算法,也可以归类为字符串处理和数组操作类型的题目。通过对输入进行解析并根据条件将小朋友分班,需要保持结果的升序排列,同时处理异常输入。

解题思路

  1. 数据解析:输入是以空格分开的小朋友编号和是否同班标志。解析时要把小朋友编号与是否同班的标志分离开。

  2. 分班:从第一个小朋友开始,使用两个列表分别存放两个班的小朋友。根据标志 Y 或 N

    判断当前小朋友应该分到哪个班:

    • 如果标志是Y,那么当前小朋友与前一个小朋友同班。
  • 如果标志是N,则当前小朋友与前一个小朋友不同班。

  1. 排序与输出:对于每个班的小朋友的编号,按照升序排列。并根据题目要求输出结果:

    • 若两个班的小朋友编号都不为空,按照第一个编号较小的班级先输出。
  • 若只有一个班的小朋友,则第二行输出空行。

  1. 异常处理:如果小朋友编号不在范围内,直接输出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 = True

    if flag == 'N':
        one = not one

    if 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;
}
    

整理题解不易, 如果有帮助到您,请给点个赞 ‍❤️‍ 和收藏 ⭐,让更多的人看到。🙏🙏🙏

#面经##华为od机试##华为od题库##华为od##华为od笔试#
全部评论
简单并查集
1 回复 分享
发布于 2024-10-27 20:10 上海

相关推荐

点赞 评论 收藏
分享
评论
3
4
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务