题意:
根据学生的成绩和排名,根据学校的招生情况,确定最终的招生结果。
输入N,M,K,代表N个学生,M个学校,每个学生有K种志愿(可以相同)
接下来的一行输入M个整数,代表这M个学校的最多录取人数
接下来的N行,每一行输入2+K个数,分别代表学生的GE(高考成绩)、GI(面试成绩)、K个志愿
录取规则:
(1)根据学生的GE和GI平均成绩从高到低排名,相等则继续比较GE,GE如果也相等则两个学生排名相同;
(2)根据排名名单,依次看学生的志愿学校;
(3)如果当前志愿学校录取人数未满则录取该生;
(4)如果两学生排名一样,且申请的是同一所学校,那么学校即使录取名额超限,也必须录取他们。
于是:可能有学生所有志愿均被刷,也可能有学校录取不到学生。
思路很简单,用两个结构体存取school和student的信息,并按照录取规则进行依次录取。
#include<stdio.h>
#include<stdlib.h>
typedef struct{
int total; // 需要录取的人数
int already; // 当前已录取的人数
int select[100]; // 录取的学生
}School; // 学校信息
typedef struct{
float GE,GI,final;
int id;
int choice[6]; // 志愿
}Student; // 学生信息
int cmp(const void *a,const void *b) // student根据成绩排序
{
Student * x = (Student*)a;
Student * y = (Student*)b;
if(x->final != y->final)
return y->final*10 - x->final*10;
else
return y->GE*10 -x->GE*10;
}
int cmp2(const void *a,const void *b) // school录取学生编号升序排序
{
int *x = (int *)a;
int *y = (int *)b;
return *x-*y;
}
int main()
{
int N,M,K;
scanf("%d %d %d",&N,&M,&K);
School school[M];
Student student[N],temp[N];
int i,j;
for(i = 0;i<M;i++)
{
scanf("%d",&school[i].total);
school[i].already = 0;
for(j = 0;j<100;j++)
school[i].select[j] = 99999;
}
for(i = 0;i<N;i++)
{
scanf("%f %f",&student[i].GE,&student[i].GI);
student[i].final = (student[i].GE + student[i].GI)/2;
student[i].id = i;
for(j = 0;j<K;j++)
scanf("%d",&student[i].choice[j]);
for(;j<6;j++)
student[i].choice[j] = -1;
}
// 在排序前将原始student信息保存在temp,用于扩招时使用(因为排序后的student下标和id不一致)
for(i = 0;i<N;i++)
{
temp[i].final = student[i].final;
temp[i].GE = student[i].GE;
}
qsort(student,N,sizeof(Student),cmp); // 学生按成绩排序
//依次遍历每个学生的每个志愿
for(i = 0;i<N;i++)
{
for(j = 0;j<K;j++)
{
int want = student[i].choice[j]; // want为当前学生当前志愿的学校编号
if(school[want].already<school[want].total) // 如果该校还未录取完毕
{
school[want].select[school[want].already] = student[i].id;
school[want].already++;
break;
}
else // 考虑是否扩招
{
//already-1下标的必是该校最后一个录进来的学生,与他比较即可。
if(temp[school[want].select[school[want].already-1]].final == student[i].final && temp[school[want].select[school[want].already-1]].GE == student[i].GE) // 如果GE和GI均相同则扩招
{
school[want].select[school[want].already] = student[i].id;
school[want].already ++;
break;
}
}
}
}
for(i = 0;i<M;i++) // 对每个学校的录取人序号升序排列
qsort(school[i].select,school[i].already,sizeof(int),cmp2);
for(i = 0;i<M;i++) // 输出学校录取情况
{
if(!school[i].already) // 没录取到学生
printf("\n");
else
{
for(j = 0;j<school[i].already;j++)
{
if(j == school[i].already-1)
printf("%d\n",school[i].select[j]);
else
printf("%d ",school[i].select[j]);
}
}
}
return 0;
}
京公网安备 11010502036488号