原题:1080. Graduate Admission (30)
解题思路:
关键在于理解题意:
1.按总分排序,总分一样按GE排序,GE也一样,则序号一样
2.按照志愿从高到低,直到最后
3.每个志愿只要目标院校没满员,或者当前学生名次和该校最后录取的学生名次一样,就录取
4.注意最后输出按照id从小到大
代码如下:
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 40000 + 5;
const int maxq = 100 + 5;
int quato[maxq];
int lastRank[maxq]; //每个学校录取的最后一个人的名次,初始为-1
vector<int> ans[maxq];
struct Stu
{
int gi, ge, r, id;
int prefer[6];
} stu[maxn];
bool cmp1(Stu a, Stu b)
{
if(a.gi + a.ge != b.gi + b.ge) return a.gi+a.ge > b.gi+b.ge;
else return a.ge > b.ge;
}
int main()
{
int n, m, k;
while(scanf("%d%d%d", &n, &m, &k) == 3)
{
for(int i = 0; i < m; i++) {scanf("%d", &quato[i]); ans[i].clear(); lastRank[i] = -1;}
for(int i = 0; i < n; i++)
{
stu[i].id = i;
scanf("%d%d", &stu[i].ge, &stu[i].gi);
for(int j = 0; j < k; j++)
scanf("%d", &stu[i].prefer[j]);
}
sort(stu, stu+n, cmp1);
stu[0].r = 1;
for(int i = 1; i < n; i++)
{
if(stu[i].ge + stu[i].gi == stu[i-1].ge + stu[i-1].gi && stu[i].ge == stu[i-1].ge)
stu[i].r = stu[i-1].r;
else
stu[i].r = i+1;
}
for(int i = 0; i < n; i++)
{
for(int j = 0; j < k; j++)
{
int schID = stu[i].prefer[j];
if(ans[schID].size() < quato[schID])
{
ans[schID].push_back(stu[i].id);
lastRank[schID] = stu[i].r;
break;
}
else if(lastRank[schID] != -1 && stu[i].r == lastRank[schID])
{
ans[schID].push_back(stu[i].id);
break;
}
}
}
for(int i = 0; i < m; i++)
{
sort(ans[i].begin(), ans[i].end());
for(int j = 0; j < ans[i].size(); j++)
{
if(j) printf(" ");
printf("%d", ans[i][j]);
}
printf("\n");
}
}
return 0;
}