[PAT-A 1080]Graduate Admission

在这里插入图片描述
在这里插入图片描述
题目大意:
有N位考生,M所学校,每位考生都有K个志愿学校,每个学校也有招生人数限制。
给出每位学生的考试成绩GE GI,以及K个志愿学校的编号。
要求模拟录取招生的过程,并输出米格学校录取的考生编号(从小到大)
录取规则:(有点像高考的平行志愿)
1)先按考生总分(GE+GI)/2进行排名,总分相同的按照GE的大小,高的在前,若GE相同,则排名相同。
2)按排名先后来考虑每个考生最终录取的学校,每个考生,按照K个志愿的先后顺序,如果当前志愿的学校招生人数未达该校招生的总人数,
那么由该所学校录取他,并不再考虑后面的志愿。
如果当前志愿学校的已招生人数已经到达招生人数的总额度,但该校上一个录取的考生排名与该考生的排名相同,则此时可以破格录取。
除以上两种情况,均视为该志愿学校无法录取考生,转而考虑考生的下一个志愿学校。
如果考生所有志愿都无法被录取,则视为落榜。

思路:
1)根据题目中涉及的信息,定义两个结构体变量Student与School
其中Student中存储 学生的两门课总分(不用处理小数),排名,考生编号,以及所填报的K个学校的编号。
School中存储 学校招生的总额度,当前实际招生人数,已经接受的考生编号,最后一个招收的考生编号。
2)cmp函数,按照排名题目要求
3)对每位考生的每个志愿学校,如果当前志愿学校的招生人数未达到该校人数总额度或该校上一个录取考生的排名与该考生的排名相同(破格的情况),则录取该考生。
4)对每个学校,将其录取的考生按照从小到大排序,按学校顺序输出。(注意是考生的编号,不是录取的顺序),最后需要再排序一次。

AC代码:

//PAT_A 1080
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Student {
	int GE, GI, sum;
	int r, stuID;
	int cho[6];//志愿编号
}stu[40010];
struct School {
	int quota;//招生人数总额度
	int stuNum;//实际招生人数
	int id[40010];//招收的学生编号d
	int lastAdmit;//最后一个招收的学生编号
}sch[110];
bool cmpStu(Student a, Student b) {
	if (a.sum != b.sum)return a.sum > b.sum;
	else return a.GE > b.GE;
}
bool cmpID(int a, int b) {
	return stu[a].stuID < stu[b].stuID;//考生编号从小到大
}
int main() {
	int n, m, k;
	(void)scanf("%d %d %d", &n, &m, &k);
	for (int i = 0; i < m; i++) {
		(void)scanf("%d", &sch[i].quota);
		sch[i].stuNum = 0;
		sch[i].lastAdmit = -1;
	}
	for (int i = 0; i < n; i++) {
		stu[i].stuID = i;
		(void)scanf("%d %d", &stu[i].GE, &stu[i].GI);
		stu[i].sum = stu[i].GE + stu[i].GI;
		for (int j = 0; j < k; j++) {
			(void)scanf("%d", &stu[i].cho[j]);
		}
	}
	sort(stu, stu + n, cmpStu);
	for (int i = 0; i < n; i++) {
		if (i > 0 && stu[i].sum == stu[i - 1].sum && stu[i].GE == stu[i - 1].GE)stu[i].r = stu[i - 1].r;
		else stu[i].r = i;
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < k; j++) {
			int choice = stu[i].cho[j];
			int num = sch[choice].stuNum;
			int last = sch[choice].lastAdmit;
			if (num < sch[choice].quota || last != -1 && stu[i].r == stu[last].r) {//两种录取的办法
				sch[choice].id[num] = i;
				sch[choice].lastAdmit = i;
				sch[choice].stuNum++;
				break;
			}
		}
	}
	for (int i = 0; i < m; i++) {
		if (sch[i].stuNum > 0) {
			sort(sch[i].id, sch[i].id + sch[i].stuNum, cmpID);//对录取的学生按编号顺序排序
			for (int j = 0; j < sch[i].stuNum; j++) {
				printf("%d", stu[sch[i].id[j]].stuID);
				if (j < sch[i].stuNum - 1)printf(" ");
			}
		}
		printf("\n");
	}
	return 0;
}


发布了101 篇原创文章 · 获赞 1 · 访问量 2980

猜你喜欢

转载自blog.csdn.net/weixin_44699689/article/details/104178323