Skip to content

Latest commit

 

History

History
86 lines (74 loc) · 3.88 KB

1080. Graduate Admission.md

File metadata and controls

86 lines (74 loc) · 3.88 KB

【PAT A-1080】Graduate Admission

题意概述

要求模拟学校志愿录取的情况。每个学生拥有两个成绩:笔试成绩(GE)、面试成绩(GI)。综合成绩(GF)计算公式为$GF=\left(GE+GI\right)/2$。要求按以下规则进行录取:

  1. 学生排名计算方法为:先按 GF 从高到低排序,如果 GF 相同,按 GE 从高到低排序。如果 GF 和 GE 都相同,则排名必须相同。
  2. 学校录取时,按排名从高到低依次录取。
  3. 采用平行志愿录取方式。每个学生可以申请 K 所学校,录取时按照申请学校的顺序依次进行录取。如果录取时学生申请的学校名额未满,则将该学生录取到这所学校,否则依次考虑他的其它志愿学校。如果一个学生未被任何志愿学校录取,那么这个学生将不幸落榜。
  4. 如果排名并列,并且相应的申请者正在同一所学校申请,那么即使超过学校录取名额,该学校也必须录取所有具有相同排名的申请者。

输入输出格式

输入第一行包含 3 个正整数:N、M、K,分别表示申请的总人数、学校总数以及每份申请所含的志愿数。之后一行给出 M 个正整数,分别表示每所学校的名额数量。然后紧接着 N 行,每行按“GE GI 志愿”的格式输入一份申请的信息。学校由 0M-1 编号,申请按 0N-1 编号。

输出所有学校的录取结果。每所学校的录取结果必须占一行,其中包含学校录取的申请人编号。编号必须按升序排列,并用空格分隔。每行的末尾必须没有多余的空格。如果没有申请人被学校录取,则必须相应地输出空白行。

数据规模

$$N\le40000,M\le100,K\le5$$

算法设计

先定义一个类 Student,其中应该包括以下几种数据成员:id、GE、GI、GF 以及志愿 app。定义一个变量 quota 存储所有学校的名额数量。读取每个学生的申请时,更新相关信息。读取完毕后,按题目要求对所有申请进行排序,并计算所有学生的排名。然后按题意模拟录取过程即可。具体实现可见代码。

C++代码

#include <bits/stdc++.h>
using namespace std;
using gg = long long;
struct Student {
    gg id, ge, gi, gf;  // gf表示最终成绩
    array<gg, 6> app;  //申请的学校
};
int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    gg ni, mi, ki;
    cin >> ni >> mi >> ki;
    vector<gg> quota(mi);
    for (gg& i : quota) {  //读取每个学校的名额数量
        cin >> i;
    }
    vector<Student> stu(ni);
    for (gg i = 0; i < ni; ++i) {  //读取每个学生的申请
        cin >> stu[i].ge >> stu[i].gi;
        for (gg j = 0; j < ki; ++j) {
            cin >> stu[i].app[j];
        }
        stu[i].gf = stu[i].ge + stu[i].gi;  //最终成绩不除2不会影响结果
        stu[i].id = i;
    }
    sort(stu.begin(), stu.end(), [](const Student& s1, const Student& s2) {
        return tie(s2.gf, s2.ge) < tie(s1.gf, s1.ge);
    });  //排序
    vector<gg> rank(ni);  //记录学生排名
    gg r = 1;
    for (gg i = 0; i < stu.size(); ++i) {  //计算排名
        if (i == 0 or stu[i].gf != stu[i - 1].gf or
            stu[i].ge != stu[i - 1].ge) {
            r = i + 1;
        }
        rank[stu[i].id] = r;
    }
    vector<vector<gg>> ans(mi);
    for (auto& s : stu) {  //统计每个学生的志愿录取情况
        for (gg i = 0; i < ki; ++i) {
            gg j = s.app[i];
            if (ans[j].size() < quota[j] or
                (not ans.empty() and rank[s.id] == rank[ans[j].back()])) {
                ans[j].push_back(s.id);
                break;
            }
        }
    }
    for (auto& v : ans) {  //输出
        sort(v.begin(), v.end());  //学生编号要升序输出
        for (gg i = 0; i < v.size(); ++i) {
            cout << (i == 0 ? "" : " ") << v[i];
        }
        cout << "\n";
    }
    return 0;
}