题目要求:
给出一组学校的拟招生人数,并给出n个学生的k个志愿学校和成绩,让你根据成绩得出每个学校的录取名单(学生的id用学生信息的初始输入次序表示)。
注意:
1. 排名规则:成绩总和 > 第一门成绩,如果都相等,则排名相同。
2. 录取规则:假设学生S
1)如果S的排名<当前志愿的剩余名额,则直接录取
2)如果志愿学校没有名额了,但S的排名与学校的最后一名录取学生的排名相同,则破格录取。
所以应该在学校的结构体中设置 “当前录取人数” “最后一位学生的排名” 的变量方便比较。
3. 输出学校录取名单时,学生的编号按照升序排列,如果某个学校没有学生录取,则空行。
学校和学生的编号都是初始的输入顺序,从0开始。用结构数组存储,注意在排序后,学生的编号是打乱的,所以应该在学生的结构体里设置一个id的变量,并初始化为输入次序。
我的代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Maxn = 40010,Maxm = 110;
struct Student{
int id;
int g1,g2,sum;
int want[6];
int rank;
}stu[Maxn];
struct School{
int all;//拟招生人数
int getnum;//当前已招收人数 初值0
int last;//当前排名最末的学生的排名 初值 -1
int id[Maxn];//当前已经招到的学生id
}sch[Maxm];
bool cmp(Student a,Student b)
{
if(a.sum!=b.sum)
return a.sum>b.sum;
else
return a.g1>b.g1;
}
bool cmp1(int a,int b)
{
return a<b;
}
int main()
{
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=0;i<m;i++) //输入招收人数
{
scanf("%d",&sch[i].all);
sch[i].getnum=0;
sch[i].last=-1;
}
for(int i=0;i<n;i++) //输入学生信息
{
stu[i].id=i;
scanf("%d%d",&stu[i].g1,&stu[i].g2);
stu[i].sum=stu[i].g1+stu[i].g2;
for(int j=0;j<k;j++)
scanf("%d",&stu[i].want[j]);
}
sort(stu,stu+n,cmp);
//处理排名
for(int i=0;i<n;i++)
{
//排名相同
if(i>0&&stu[i].sum==stu[i-1].sum&&stu[i].g1==stu[i-1].g1)
stu[i].rank=stu[i-1].rank;
else
stu[i].rank = i;
// printf(" id为%d的学生的排名是%d\n",stu[i].id,stu[i].rank );
}
//处理录取
for(int i=0;i<n;i++)
{
//枚举该考生的所有志愿
for(int j=0;j<k;j++)
{
int choose = stu[i].want[j]; //当前志愿学校的id
// printf("*****当前学校是%d,学生是%d\n******",choose,stu[i].id);
if(sch[choose].all>sch[choose].getnum||sch[choose].last==stu[i].rank)
{
sch[choose].id[sch[choose].getnum]=stu[i].id;//已招到学生id更新
sch[choose].getnum++;//已招到人数+1
sch[choose].last=stu[i].rank;//最后一位的名次更新
break; //bug在这
}
}
}
//输出每个学校的录取信息
for(int i=0;i<m;i++)
{
int num=sch[i].getnum;//当前学校已招到人数
sort(sch[i].id,sch[i].id+num,cmp1);
if(num>0)
{
for(int j=0;j<num;j++)
{
printf("%d",sch[i].id[j]);
// printf(" *rank=%d* ",stu[sch[i].id[j]].rank );
if(j<num-1)
printf(" ");
}
}
printf("\n");
}
return 0;
}