题目链接
题目分析
【学生排名规则】 1、平均分; 2、GE; 3、否则排名相同;
【录取规则】
- 依 名次 从高往低 录取
- 前一志愿满了 滑档 到后一志愿,全滑档则不录取
- 同一排名的多人 报同一学校,即使该学校只有一个名额也要全录取
解题思路
并不难,按题意顺序写就行;注意录取细节。
1、结构体分别保存student
、school
信息;
2、根据规则对student
结构体排序,并标记排名;
3、按学生排名,根据规则从高到低逐个录取
AC程序(C++)
/**************************
*@Author: 3stone
*@ACM: PAT.A1080 Graduate Admission
*@Time: 17/3/2
*@IDE: VS 2017
***************************/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<set>
using namespace std;
#define maxn 40005
struct Student {
int id; //初始编号
int GE, GI, final_grade; //成绩
int app[8]; //志愿
int rank; //排名
}stu[maxn];
struct School {
int sch_quota; //招生定额
int last_stu_admitted; //上一个招收学生的编号
int num_admitted; //招生人数
set<int> stu_admitted; //招收学生的编号
}school[110];
bool cmp(Student s1, Student s2) {
if (s1.final_grade != s2.final_grade)
return s1.final_grade > s2.final_grade;
else
return s1.GE > s2.GE;
}
int main() {
// 申请人数, 学校数, 最大志愿数
int app_num, sch_num, cho_num;
while(scanf("%d%d%d", &app_num, &sch_num, &cho_num) != EOF) {
//输入 & 初始化
for(int i = 0; i < sch_num; i++){
scanf("%d", &school[i].sch_quota);
school[i].num_admitted = 0; //初始未招人
school[i].last_stu_admitted = -1; //最后一个录取学生编号
}
for(int i = 0; i < app_num; i++){
stu[i].id = i;
scanf("%d%d", &stu[i].GE, &stu[i].GI);
stu[i].final_grade = (stu[i].GE + stu[i].GI);
for(int j = 0; j < cho_num; j++)
scanf("%d", &stu[i].app[j]);
}
sort(stu, stu + app_num, cmp);
//记录 排名
for(int i = 0; i < app_num; i++){
if(i > 0 && stu[i].final_grade == stu[i - 1].final_grade && stu[i].GE == stu[i - 1].GE)
stu[i].rank = stu[i - 1].rank;
else
stu[i].rank = i;
//printf("stu: %d %d %d\n", stu[i].id, stu[i].final_grade, stu[i].rank); //检查排名
}
//录取
int cur_choice, last_stu;
for(int i = 0; i < app_num; i++) { //按学生排名从高到低筛选
for(int j = 0; j < cho_num; j++) { //按此学生的志愿依次筛选
cur_choice = stu[i].app[j]; //当前志愿学校编号
last_stu = school[cur_choice].last_stu_admitted; //此学校上一个招收的学生
// 第一个判断条件:同名次都录取
if (school[cur_choice].num_admitted < school[cur_choice].sch_quota
|| (last_stu != -1 && stu[last_stu].rank == stu[i].rank)){//还没录满,录取
school[cur_choice].num_admitted++;
school[cur_choice].last_stu_admitted = i;
school[cur_choice].stu_admitted.insert(stu[i].id);
break;
}
}
}
//输出 结果
for(int i = 0; i < sch_num; i++){ //按学校编号
if(school[i].num_admitted == 0){ //未录取
printf("\n");
continue;
}
//迭代器输出 录取学生编号
set<int>::iterator set_end = school[i].stu_admitted.end();
set<int>::iterator it = school[i].stu_admitted.begin();
printf("%d", *it);
for(++it; it != set_end; it++) {
printf(" %d", *it);
}
printf("\n");
}
}//while-scanf
return 0;
}