#P3022. 分班(100分)
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 335
            Accepted: 56
            Difficulty: 2
            
          
          
          
                       所属公司 : 
                              华为od
                                
            
                      
          
 
- 
                        算法标签>模拟          
 
分班(100分)
题目描述
幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班,请你帮忙把同班的小朋友找出来。
小朋友的编号是整数,与前一位小朋友同班用 Y 表示,不同班用 N 表示。
输入描述:输入为空格分开的小朋友编号和是否同班标志,比如:
6/N 2/Y 3/N 4/Y
表示 4 位小朋友,2 和 6 同班,3 和 2 不同班,4 和 3 同班。小朋友总数不超过 999,每个小朋友编号大于 0,小于等于 999。不考虑输入格式错误问题。
输出描述:输出为两行,每一行记录一个班小朋友的编号,编号用空格分开,且按升序排列。若只有一个班的小朋友,第二行为空行。若输入不符合要求,直接输出 ERROR。
解题思路
- 输入验证:检查每个编号和标志是否合法,编号应在 [1, 999] 范围内,并且第一个小朋友的标志不能为 
Y。若验证不通过,输出ERROR。 - 分班逻辑:用两个列表 
class1和class2来分别存放两个班的学生编号,isClass1和isClass2来分别表示上一个学生在哪一个班级。根据Y或N的标志来决定编号应加入哪个班。- 若标志为 
Y,表示与前一位小朋友同班,加入当前班级; - 若标志为 
N,表示与前一位小朋友不同班,切换班级。 
 - 若标志为 
 - 排序输出:将两个班的编号分别排序后输出,编号小的班排在第一行,编号大的班排在第二行。
 
复杂度分析
- 时间复杂度:O(n * log(n)),主要用于对两个班级的编号排序。
 - 空间复杂度:O(n),存储两个班级的编号。
 
代码实现
C++
#include <bits/stdc++.h>
using namespace std;
// 检查编号和标志的合法性
bool check(int id, char flag, bool isFirst) {
    if (id <= 0 || id > 999) {  // 编号应在1到999范围内
        cout << "ERROR";
        return false;
    }
    if (isFirst && flag == 'Y') {  // 第一个小朋友的标志不能是Y
        cout << "ERROR";
        return false;
    }
    return true;
}
int main() {
    bool isFirst = true;  // 标记是否是第一个小朋友
    bool isClass1 = false;  // 当前班级是否为class1
    vector<int> class1, class2;  // 存放两个班的小朋友编号
    int id;  // 小朋友编号
    char flag;  // 是否同班标志
    int num = 0;  // 计数小朋友总数
    // 输入处理
    while (cin >> id) {
        getchar();
        cin >> flag;
        if (!check(id, flag, isFirst)) {  // 检查输入合法性
            return 0;
        }
        isFirst = false;
        // 根据标志Y/N决定加入哪个班级
        if ((flag == 'Y' && isClass1) || (flag == 'N' && !isClass1)) {
            isClass1 = true;
            class1.emplace_back(id);
        } else {
            isClass1 = false;
            class2.emplace_back(id);
        }
        num++;
    }
    if (num > 999) {  // 小朋友总数不应超过999
        cout << "ERROR";
        return 0;
    }
    // 对两个班级的编号进行排序
    sort(class1.begin(), class1.end());
    sort(class2.begin(), class2.end());
    // 保证编号小的班级输出在前
    if (class1.empty() || (!class2.empty() && class1[0] > class2[0])) {
        swap(class1, class2);
    }
    // 输出结果
    for (auto i : class1) cout << i << " ";
    cout << endl;
    for (auto i : class2) cout << i << " ";
    cout << endl;
    return 0;
}
Python
def check(id, flag, is_first):
    if id <= 0 or id > 999:  # 编号应在1到999范围内
        print("ERROR")
        return False
    if is_first and flag == 'Y':  # 第一个小朋友的标志不能是Y
        print("ERROR")
        return False
    return True
def main():
    is_first = True
    is_class1 = False
    class1, class2 = [], []
    num = 0
    
    # 输入处理
    try:
        inputs = input().split()
        for entry in inputs:
            id, flag = entry.split('/')
            id = int(id)
            if not check(id, flag, is_first):
                return
            is_first = False
            if (flag == 'Y' and is_class1) or (flag == 'N' and not is_class1):
                is_class1 = True
                class1.append(id)
            else:
                is_class1 = False
                class2.append(id)
            num += 1
        if num > 999:  # 小朋友总数不应超过999
            print("ERROR")
            return
    except:
        print("ERROR")
        return
    
    # 对两个班级的编号进行排序
    class1.sort()
    class2.sort()
    
    # 保证编号小的班级输出在前
    if class1 and (not class2 or class1[0] < class2[0]):
        print(" ".join(map(str, class1)))
        print(" ".join(map(str, class2)))
    else:
        print(" ".join(map(str, class2)))
        print(" ".join(map(str, class1)))
main()
Java
import java.util.*;
public class Main {
    // 检查编号和标志的合法性
    public static boolean check(int id, char flag, boolean isFirst) {
        if (id <= 0 || id > 999) {  // 编号应在1到999范围内
            System.out.println("ERROR");
            return false;
        }
        if (isFirst && flag == 'Y') {  // 第一个小朋友的标志不能是Y
            System.out.println("ERROR");
            return false;
        }
        
        return true;
    }
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        boolean isFirst = true;
        boolean isClass1 = false;
        List<Integer> class1 = new ArrayList<>();
        List<Integer> class2 = new ArrayList<>();
        int num = 0;
        try {
            while (scanner.hasNext()) {
                String[] parts = scanner.next().split("/");
                int id = Integer.parseInt(parts[0]);
                char flag = parts[1].charAt(0);
                if (!check(id, flag, isFirst)) {
                    return;
                }
                isFirst = false;
                if ((flag == 'Y' && isClass1) || (flag == 'N' && !isClass1)) {
                    isClass1 = true;
                    class1.add(id);
                } else {
                    isClass1 = false;
                    class2.add(id);
                }
                num++;
            }
            if (num > 999) {  // 小朋友总数不应超过999
                System.out.println("ERROR");
                return;
            }
        } catch (Exception e) {
            System.out.println("ERROR");
            return;
        }
        // 对两个班级的编号进行排序
        Collections.sort(class1);
        Collections.sort(class2);
        // 保证编号小的班级输出在前
        if (class1.isEmpty() || (!class2.isEmpty() && class1.get(0) > class2.get(0))) {
            List<Integer> tmp = class1;
            class1 = class2;
            class2 = tmp;
        }
        // 输出结果
        for (int i : class1) System.out.print(i + " ");
        System.out.println();
        for (int i : class2) System.out.print(i + " ");
        System.out.println();
    }
}
        题目描述
幼儿园两个班的小朋友在排队时混在了一起,每位小朋友都知道自己是否与前面一位小朋友同班,请你帮忙把同班的小朋友找出来。
小朋友的编号是整数,与前一位小朋友同班用 Y 表示,不同班用 N 表示。
输入描述
输入为空格分开的小朋友编号和是否同班标志。
比如:6/N 2/Y 3/N 4/Y,表示 4 位小朋友, 2 和 6 同班,3 和 2 不同班,4 和 3 同班。
其中,小朋友总数不超过 999 ,每个小朋友编号大于 0 ,小于等于 999 。
不考虑输入格式错误问题。
输出描述
输出为两行,每一行记录一个班小朋友的编号,编号用空格分开,且:
编号需按照大小升序排列,分班记录中第一个编号小的排在第一行。
若只有一个班的小朋友,第二行为空行。
若输入不符合要求,则直接输出字符串 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
样例2
输入
1/N 2/Y 3/N 4/Y 5/Y
输出
1 2
3 4 5