✍个人博客:https://blog.csdn.net/Newin2020?spm=1011.2415.3001.5343
专栏地址:PAT题解集合
原题地址:题目详情 - 1080 Graduate Admission (pintia.cn)
中文翻译:研究生入学
专栏定位:为想考甲级PAT的小伙伴整理常考算法题解,祝大家都能取得满分!
❤️如果有收获的话,欢迎点赞收藏,您的支持就是我创作的最大动力
It is said that in 2011, there are about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.
Each applicant will have to provide two grades: the national entrance exam grade GE, and the interview grade GI. The final grade of an applicant is (GE+GI)/2. The admission rules are:
- The applicants are ranked according to their final grades, and will be admitted one by one from the top of the rank list.
- If there is a tied final grade, the applicants will be ranked according to their national entrance exam grade GE. If still tied, their ranks must be the same.
- Each applicant may have K choices and the admission will be done according to his/her choices: if according to the rank list, it is one’s turn to be admitted; and if the quota of one’s most preferred shcool is not exceeded, then one will be admitted to this school, or one’s other choices will be considered one by one in order. If one gets rejected by all of preferred schools, then this unfortunate applicant will be rejected.
- If there is a tied rank, and if the corresponding applicants are applying to the same school, then that school must admit all the applicants with the same rank, even if its quota will be exceeded.
Input Specification:
Each input file contains one test case.
Each case starts with a line containing three positive integers: N (≤40,000), the total number of applicants; M (≤100), the total number of graduate schools; and K (≤5), the number of choices an applicant may have.
In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.
Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant’s GE and GI, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M−1, and the applicants are numbered from 0 to N−1.
Output Specification:
For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants’ numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.
Sample Input:
11 6 3 2 1 2 2 2 3 100 100 0 1 2 60 60 2 3 5 100 90 0 3 4 90 100 1 2 0 90 90 5 1 3 80 90 1 0 2 80 80 0 1 2 80 80 0 1 2 80 70 1 3 2 70 80 1 2 3 100 100 0 2 4
Sample Output:
0 10 3 5 6 7 2 8 1 4
需要写个程序来处理学生的入学申请书,每个学生都会提供两个成绩:全国入学考试成绩 GE
和面试成绩 GI
。
而录取的规则如下:
GE
成绩由高到低进行排名,如果成绩仍然并列,则并列者的排名必须相同。K
个志愿,并且将根据他/她的志愿进行录取:如果按照排名列表,轮到某位学生被录取了,并且其第一志愿学校还未招满人,则他成功被该学校录取。如果名额已满,则按顺序考虑其他志愿,直至成功被录取为止。如果所有报名学校都无法录取该名学生,则该名学生录取失败。按照题意进行模拟,具体思路如下:
wish
数组来保存每个学生的志愿,先根据名额数是否超限找出每个学生最终的录取情况,最后再统一更新到答案数组中。#include
using namespace std;
const int N = 40010, M = 110, K = 5;
int n, m, k;
int wish[N];
int cnt[M];
vector<int> uty[M];
//定义学生结构体
struct Person
{
int id, ge, gi;
int wish[K];
//返回成绩之和
int total()const
{
return ge + gi;
}
//重载比较运算符
bool operator<(const Person& t)const
{
if (total() != t.total()) return total() > t.total();
else return ge > t.ge;
}
//重载等于运算符
bool operator==(const Person& t)const
{
return ge == t.ge && gi == t.gi;
}
}p[N];
int main()
{
scanf("%d%d%d", &n, &m, &k);
//输入学校和学生的信息
for (int i = 0; i < m; i++) scanf("%d", &cnt[i]);
for (int i = 0; i < n; i++)
{
p[i].id = i;
scanf("%d%d", &p[i].ge, &p[i].gi);
for (int j = 0; j < k; j++) scanf("%d", &p[i].wish[j]);
}
//对学生成绩进行排序,成绩高的同学优先选择学校
sort(p, p + n);
//初始化临时存储志愿信息的数组
memset(wish, -1, sizeof wish);
//开始计算录取情况
for (int i = 0; i < n;)
{
//找出成绩相同的同学
int j = i + 1;
while (j < n && p[i] == p[j]) j++;
//为每个人分配学校
for (int t = i; t < j; t++)
for (int u = 0; u < k; u++)
{
int w = p[t].wish[u];
//判断名额是否已经超额
if (cnt[w] > uty[w].size())
{
wish[t] = w;
break;
}
}
//将分配结果更新到结果数组
for (int t = i; t < j; t++)
if (wish[t] != -1)
uty[wish[t]].push_back(p[t].id);
//更新指针
i = j;
}
//打印录取结果
for (int i = 0; i < m; i++)
{
if (uty[i].size() > 0)
{
//需按照编号升序排序
sort(uty[i].begin(), uty[i].end());
printf("%d", uty[i][0]);
for (int j = 1; j < uty[i].size(); j++)
printf(" %d", uty[i][j]);
}
puts("");
}
return 0;
}