解题思路
- 题目条件第一条:先排序按成绩大小
- 题目条件第二条:按照指定的规则排序,总分相同比GE,GE相同排名相同
- 题目条件第三条:按照学生的排名进行录取,如果该学校满了,则跳去学生的第二志愿,依此下去
- 题目条件第四条:排名相同的且志愿相同的同时录取(可以记录每个学校的靠后的排名,如果后面排名相同就进行补录)
用set可以进行升序,记录学生数
code
#include <bits/stdc++.h>
using namespace std;
struct node{
int id,ge,gi,g,rank,choice[5];
};
bool cmp(node a,node b){
return a.g!=b.g?a.g>b.g:a.ge>b.ge;
}
int main(){
int n,m,k;
cin>>n>>m>>k;
node stu[n];
set<int> ans[m];
int paiming[m],quato[m];;
for(int i=0;i<m;i++) cin>>quato[i];
for(int i=0;i<n;i++){
cin>>stu[i].ge>>stu[i].gi;
stu[i].g=stu[i].ge+stu[i].gi;
for(int j=0;j<k;j++) cin>>stu[i].choice[j];
stu[i].id=i;
}
sort(stu,stu+n,cmp);
stu[0].rank=1;
for(int i=1;i<n;i++){
if(stu[i].g==stu[i-1].g&&stu[i].ge==stu[i-1].ge)
stu[i].rank=stu[i-1].rank;
else stu[i].rank=i+1;
}
for(int i=0;i<n;i++)
for(int j=0;j<k;j++){
if(ans[stu[i].choice[j]].size()<quato[stu[i].choice[j]]||stu[i].rank==paiming[stu[i].choice[j]]){
ans[stu[i].choice[j]].insert(stu[i].id);
paiming[stu[i].choice[j]]=stu[i].rank;
break;
}
}
for(int i=0,fir=0;i<m;fir=0,i++){
for(auto it:ans[i]){
fir?cout<<' '<<it:cout<<it;
fir=1;
}
cout<<endl;
}
return 0;
}