天梯赛的赛场安排[天梯赛]

题目描述

在这里插入图片描述
在这里插入图片描述

输入样例
10 30
zju 30
hdu 93
pku 39
hbu 42
sjtu 21
abdu 10
xjtu 36
nnu 15
hnu 168
hsnu 20


输出样例
zju 1
hdu 4
pku 2
hbu 2
sjtu 1
abdu 1
xjtu 2
nnu 1
hnu 6
hsnu 1
16

思路

模拟

存储结构
1.用结构体数组存储学校信息,包括学校编号,姓名,联系的监考老师数量
2.用优先队列存储每个学校的人数及其编号==(优化排序的复杂度)==
3.用一个数组存储空教室的信息

具体流程
1.不断取出优先队列的头元素,直至队列元素为空
2.判断当前学校的人数stu_num与教室最大容量c的关系
①stu_num >= c,开辟新房间,更新学校人数,联系监考老师+1,如果在安排后该学校仍有未安排进考场的学生,则再次将其入队
②stu_num < c,搜索已有房间,用flag标志是否有可用房间,如果有将其放入,否则开辟新房间。最后将该学校的未安排人数置零,联系监考老师+1,不用再次入队

AC代码

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> PII;
typedef struct
{
    int id; //学校编号
    string name; //学校名称
    int coach_num; //教练数量
}school;
vector<school> sch_info; //学校信息数组
vector<int> room; //房间数组
priority_queue<PII, vector<PII>, less<PII>> sch_person; //学校人数数组
int main()
{
    int n, c;
    cin >> n >> c;
    
    string name;
    int num;
    for(int i = 0; i < n; i ++)
    {
        cin >> name >> num;
        sch_info.push_back({i, name, 0});
        sch_person.push({num, i}); 
    }

    int cnt = 0; //房间数量
    while(sch_person.size())
    {
        //取出队首元素,即为未安排人数最多的学校
        PII temp = sch_person.top();
        sch_person.pop();

        //取出该学校信息
        int &stu_num = temp.first;
        int sch_id = temp.second;

        if(stu_num >= c)
        {
            cnt ++; //开一个新房间
            stu_num -= c; //更新该学校未安排考场的人数
            sch_info[sch_id].coach_num ++; //对应学校需要联系的监考人+1
            if(stu_num) sch_person.push(temp); //如果该学校仍有人未安排,再次将其入队
        }
        else
        {
            bool flag = false; //标记已存在的教室是否有可用的
            for(int i = 0; i < room.size(); i ++)
            {
                if(room[i] + stu_num <= c)
                {
                    flag = true;
                    room[i] += stu_num; //更新空教室的剩余人数
                    break;
                }
            }

            if(!flag) //没有教室可用
            {
                cnt ++; //新开一个教室
                room.push_back(stu_num);
            }

            sch_info[sch_id].coach_num ++;
            stu_num = 0;
        }
    }

    for(int i = 0; i < n; i ++)
        cout << sch_info[i].name << " " << sch_info[i].coach_num << endl;
    cout << cnt << endl;
    return 0;
}

欢迎大家批评指正!!!

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值