PAT:1080. Graduate Admission (30) AC
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct Student
{
int GE,GI,sum,rank,ID;
int prefer[6];
}STU[40066];
struct School
{
int want; //各学校招生人数
int get; //已招到的人数
int line; //最后一名进来的排名线
int queue[40066]; //已投档学生编号
}SC[106];
bool cmp(Student a,Student b)
{
if(a.sum!=b.sum)
return a.sum>b.sum;
else
return a.GE>b.GE;
}
int main()
{
memset(STU,0,sizeof(STU));
memset(SC,0,sizeof(SC));
int n,m,k; //n名考生,m所学校,k个志愿
scanf("%d%d%d",&n,&m,&k);
for(int i=0 ; i<m ; ++i) //输入各学校招生人数
scanf("%d",&SC[i].want);
for(int i=0 ; i<n ; ++i)
{
scanf("%d %d",&STU[i].GE, &STU[i].GI); //填入分数
STU[i].sum=STU[i].GE+STU[i].GI; //填入总分
STU[i].ID=i; //填入编号
for(int j=0 ; j<k ; ++j)
{
int tmp=-1;
scanf("%d",&tmp); //填入志愿
STU[i].prefer[j]=tmp;
}
}
sort(STU,STU+n,cmp);
STU[0].rank=1;
for(int i=1 ; i<n ; ++i) //填入排序
{
if(STU[i].sum==STU[i-1].sum && 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) //STU[i].prefer[j]代表考生的j号志愿学校代码
{
if(SC[STU[i].prefer[j]].want>SC[STU[i].prefer[j]].get || SC[STU[i].prefer[j]].line==STU[i].rank ) //该校未招满或者已招满但考生排名和最后一个找入学生一样
{
SC[STU[i].prefer[j]].queue[SC[STU[i].prefer[j]].get]=STU[i].ID; //考生i的ID入档
++SC[STU[i].prefer[j]].get; //入档学生数+1
SC[STU[i].prefer[j]].line=STU[i].rank; //更新最后名次
break; //已被录取
}
}
}
//输出
for(int i=0 ; i<m ; ++i)
{
sort(SC[i].queue,SC[i].queue+SC[i].get); //最后升序排列
for(int j=0 ; j<SC[i].get ;++j)
{
printf("%d",SC[i].queue[j]);
if(j!=SC[i].get-1)
printf(" ");
}
printf("\n");
}
return 0;
}