PAT A1080 Graduate Admission

这篇博客详细介绍了PAT A1080 Graduate Admission的模拟录取过程,包括录取规则、排序标准和处理并列问题的方法。博主提出了双指针法的解决方案,通过排序考生并使用[left, right)区间处理同排名考生,确保能同时进入同一学校。此外,还提及了使用邻接链表来存储同排名学生,并通过遍历和管理学校名额来实现录取。提供了不同阶段的代码思路,从T2到T4,逐步完善解决方案。" 131705967,8515779,Spring Boot与ElasticsearchRepository深度整合,"['spring boot', '后端', 'elasticsearch', '数据仓库', '数据操作']
摘要由CSDN通过智能技术生成

PAT A1080 Graduate Admission

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Sample Input:

11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4

Sample Output:

0 10
3
5 6 7
2 8

1 4
word meaning
automate vt. 使自动化
admitted v. 承认
quota n. 配额
  • 题意:
    模拟学校录取,每个学校名额存在quota[ ]里
    每个考生有两个成绩:初试GE,复试GI,及志愿表pSchool[ ]
    排序规则:先按平均分(==总分),再按GE,都同并列(★并列问题)
    排好序后,从第一名开始选学校,每个人都是从第一志愿开始,一直向后匹配:直到匹配到1)学校有名额2)和人并列进同一学校,或者匹配到最后一个志愿也没匹配成功 -> 没学上了
    输出每个学校招的学生(递增),结尾不多空格,没有招到输出空行

  • 思路 1:双指针法
    将所有考生排序后,用[left , right)框住同一"排名"的人,这样从头到尾一组一组处理(以解决:并列进同一个学校的问题),若一个人有学上,就把他加入到对应学校的vector中去,最后循环将每个学校的vector排序输出

  • code 1:

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
using namespace std;
int n, m, k;
int quota[110];
vector<int> admit[110];	//存储各学校招生情况 
struct Stu{
   
	int id, gE, gI, fG, pSchool[6];
}stu[400100];
bool cmp(Stu& a, Stu& b){
   
//TIPS 1: 这里要使用&引用传参,不然会超时! 
	if(a.fG != b.fG) return a.fG > b.fG;
	else return a.gE > b.gE;
}
int main(){
   
	scanf("%d %d %d", &n, &m, &k);
	for(int i = 0; i < m; ++i){
   
		scanf("%d", &quota[i]);
	}
	for(int i = 0; i < n; ++i){
   
		scanf("%d %d", &stu[i].gE, &stu[i].gI);
		stu[i].id = i;
		stu[i].fG = stu[i].gE + stu[i].gI;
		for(int j = 0; j < k; ++j){
   
			scanf("%d", &stu[i].pSchool[j]);
		}
	}
	sort(stu, stu+n, cmp);
	int left = 0, right = 0;
	while(right < n){
   
		while(stu[right].fG == stu[left].fG && stu[right].gE == stu[left].gE && right < n){
   
		//Wrong 1: 这个循环条件导致了最后一个测试点 段错误: 
		//如果right不加限制,后面都是0可能会一直累加下去,导致while执行判断条件时数组越界 
			right++;
		} 
		int preS = -1; 	//上一个人去的学校  TIPS 2:每轮循环开始置为-1,防止边界出问题 	
		for(int i = left; i < right; ++i){
   
			for(int j = 0; j < k; ++j){
   
				if(quota[stu[i].pSchool[j]] > 0){
   
				//如果学校还有名额
					quota[stu[i].pSchool[j]]--;
					admit[stu[i].pSchool[j]].push_back(stu[i].id);
					preS = stu[i].pSchool[j];
					break<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值