本文已参与「新人创作礼」活动,一起开启掘金创作之路。
1566. 研究生入学
原题传送:AcWing 1566. 研究生入学
据说, 年,浙江省约有 所研究生院准备着手处理 多份入学申请。
如果你可以编写一个程序来自动执行录取流程,那将会很有帮助。
每个申请人都必须提供两个成绩:全国入学考试成绩 和面试成绩 ,申请人的最终成绩是 。
录取规则如下:
- 申请者将根据其最终成绩由高到低进行排名,并且将从排名列表的顶部开始逐一录取。
- 如果申请者的最终成绩并列,则按照 成绩由高到低进行排名,如果成绩仍然并列,则并列者的排名必须相同。
- 每个申请人可以填报 个志愿,并且将根据他/她的志愿进行录取:如果按照排名列表,轮到某位学生被录取了,并且其第一志愿学校还未招满人,则他成功被该学校录取。如果名额已满,则按顺序考虑其他志愿,直至成功被录取为止。如果所有报名学校都无法录取该名学生,则该名学生录取失败。
- 如果出现并列排名,并且并列申请人正在申请同一所学校,那么该学校不得只录取其中一部分申请人,即使超过招生限额,也必须全部录取。
输入格式
第一行包含三个整数, 表示总申请人数量, 表示学校数量, 表示可填报志愿数量。
第二行包含 个整数,表示每所学校的计划招生人数。
接下来 行,每行包含 个整数,前两个整数表示一名申请人的 和 ,接下来 个整数,表示该申请人的志愿学校编号。
所有学校编号 ,所有申请人编号 。
输出格式
输出所有研究生院的录取结果。
每所学校的录取结果占据一行,其中包含所有学校录取的申请人的编号。编号必须按升序排列,并用空格分隔。
每行的末尾必须没有多余的空格。
如果某学校没有录取任何学生,则必须相应地输出空白行。
数据范围
, , , , 每所学校的计划招生人数不会超过 。
输入样例:
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
输出样例:
0 10
3
5 6 7
2 8
1 4
思路:
先根据提意列出排名,从第一志愿开始录取,若成绩并列,则记录录取的学校,然后一起加入vector更新学校招生容量。
题解:
#include<bits/stdc++.h>
using namespace std;
const int N = 40010, M = 110, K = 5;
int n, m, k;
int cnt[N], wish[N];
vector<int> v[M];
struct Student
{
int id, score1, score2, sum;
int wish[K];
bool operator< (const Student &t) const
{
if(sum != t.sum)
return sum > t.sum;
return score1 > t.score1;
}
bool operator== (const Student &t) const
{
return score1 == t.score1 && score2 == t.score2;
}
}s[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++)
{
s[i].id = i;
scanf("%d%d", &s[i].score1, &s[i].score2);
for(int j = 0; j < k; j++)
scanf("%d", &s[i].wish[j]);
s[i].sum = s[i].score1 + s[i].score2;
}
sort(s, s + n);
memset(wish, -1, sizeof wish);
for(int i = 0; i < n;)
{
int j = i + 1;
while(j < n && s[i] == s[j])
j++;
for(int t = i; t < j; t++)
{
for(int u = 0; u < k; u++)
{
int w = s[t].wish[u];
if(cnt[w] > v[w].size())
{
wish[t] = w;
break;
}
}
}
for(int t = i; t < j; t++)
if(wish[t] != -1)
v[wish[t]].push_back(s[t].id);
i = j;
}
for(int i = 0; i < m; i++)
{
if(v[i].size())
{
sort(v[i].begin(), v[i].end());
printf("%d", v[i][0]);
for(int j = 1; j < v[i].size(); j++)
printf(" %d", v[i][j]);
}
printf("\n");
}
return 0;
}