23-C2-7-5 座位安排

7-5 座位安排

在某次上机考试时,座位安排规则如下:

  • 先按考生姓名的字典序排列,若姓名相同则再按学号升序排序;在排好序之后依次从1号机位开始安排座位;
  • 若某个机位的电脑损坏了,则原来安排在该位置上的考生从当前最后一位考生之后的机位开始重新安排。

请根据输入的学生信息及电脑损坏的机位,安排好该次考试的学生座位。

输入格式:

首先输入一个正整数T,表示测试数据的组数。对于每组测试数据,首先输入一个整数n(1<n<=80),表示考生数;然后输入n行,每行包含2个以一个空格间隔的字符串,分别表示一个考生的学号(长度不超过10,且仅包含数字字符,可能以0开头)和姓名(长度不超过15,且仅包含英文字母);最后输入一行整数,其中第一个整数m(1<=m<=20)表示损坏电脑的数量,接着是m个电脑损坏的机位(不超过n)。

输出格式:

对于每组测试,输出n+1行,第1行是“Case i:”,其中i是该组测试的序号(从1开始),接着输出n个座位安排信息“xxx:sno sname”,其中xxx表示以3位整数表示的座位号(不足3位则左补0),sno、sname分别表示该座位上考生的学号和姓名。另外,要求每两组测试之间留一个空行。

输入样例:

3
5
01004 Zhangsan
01002 Lisi
01003 Wangwu
01005 Zhaoliu
01001 Lisi
3 5 1 3
5
1004 Zhangsan
1002 Lisi
1003 Wangwu
1005 Zhaoliu
1001 Lisi
1 5
20
20045 Zhangsan
10022 Lisi
10013 Wangwu
10005 Zhaoliu
20001 Lisi
01004 Zhangsan
01002 Lisi
01003 Wangwu
01005 Zhaoliu
01001 Lisi
10045 Zhangsan
20022 Lisi
20013 Wangwu
20005 Zhaoliu
120001 Lisi
101004 Zhangsan
101002 Lisi
101003 Wangwu
101005 Zhaoliu
101001 Lisi
5 19 13 20 7 4

输出样例:

Case 1:
002:01002 Lisi
004:01004 Zhangsan
006:01001 Lisi
007:01003 Wangwu
008:01005 Zhaoliu

Case 2:
001:1001 Lisi
002:1002 Lisi
003:1003 Wangwu
004:1004 Zhangsan
006:1005 Zhaoliu

Case 3:
001:01001 Lisi
002:01002 Lisi
003:10022 Lisi
005:101002 Lisi
006:120001 Lisi
008:20022 Lisi
009:01003 Wangwu
010:10013 Wangwu
011:101003 Wangwu
012:20013 Wangwu
014:10045 Zhangsan
015:101004 Zhangsan
016:20045 Zhangsan
017:01005 Zhaoliu
018:10005 Zhaoliu
021:101001 Lisi
022:20001 Lisi
023:01004 Zhangsan
024:101005 Zhaoliu
025:20005 Zhaoliu

提示:

对于样例1

初始安排:
1号位:01001 Lisi
2号位:01002 Lisi
3号位:01003 Wangwu
4号位:01004 Zhangsan
5号位:01005 Zhaoliu

损坏的电脑编号:1 3 5

因1号电脑损坏,01001 Lisi排6号位
因3号电脑损坏,01003 Wangwu排7号位
因5号电脑损坏,01005 Zhaoliu排8号位

最终安排:
2号位:01002 Lisi
4号位:01004 Zhangsan
6号位:01001 Lisi
7号位:01003 Wangwu
8号位:01005 Zhaoliu

参考答案

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
#include <iomanip>

struct Student {
    std::string sno;
    std::string sname;
};

// 比较函数,用于排序学生
bool compareStudents(const Student& a, const Student& b) {
    if (a.sname == b.sname) {
        return a.sno < b.sno;
    }
    return a.sname < b.sname;
}

int main() {
    int T; // 测试数据组数
    std::cin >> T;
    for (int case_number = 1; case_number <= T; ++case_number) {
        int n; // 学生数
        std::cin >> n;
        std::vector<Student> students(n);
        for (int i = 0; i < n; ++i) {
            std::cin >> students[i].sno >> students[i].sname;
        }

        std::sort(students.begin(), students.end(), compareStudents);

        int m; // 损坏的电脑数量
        std::cin >> m;
        std::vector<int> damaged_positions(m);
        for (int i = 0; i < m; ++i) {
            std::cin >> damaged_positions[i];
        }
        std::sort(damaged_positions.begin(), damaged_positions.end());

        // 初始座位分配
        std::map<int, Student> seat_assignment;
        for (int i = 0; i < n; ++i) {
            seat_assignment[i + 1] = students[i];
        }

        // 调整损坏电脑的座位
        std::map<int, Student> adjusted_seating;
        int free_seat = n + 1;
        for (int seat = 1; seat <= n; ++seat) {
            if (std::find(damaged_positions.begin(), damaged_positions.end(), seat) != damaged_positions.end()) {
                // 寻找新的可用座位
                while (adjusted_seating.find(free_seat) != adjusted_seating.end()) {
                    ++free_seat;
                }
                adjusted_seating[free_seat] = seat_assignment[seat];
            } else {
                adjusted_seating[seat] = seat_assignment[seat];
            }
        }

        // 输出结果
        if (case_number > 1) {
            std::cout << std::endl; // 每两组测试之间留一个空行
        }
        std::cout << "Case " << case_number << ":\n";
        for (const auto& [seat, student] : adjusted_seating) {
            std::cout << std::setw(3) << std::setfill('0') << seat << ":"
                      << student.sno << " " << student.sname << "\n";
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值