PAT 1080 Graduate Admission C++版

版权声明:如若转载,请联系作者。 https://blog.csdn.net/liu16659/article/details/89504394

PAT 1080 Graduate Admission C++

1.题意

模拟研究生院招生录取过程。
浙大每年都有很多人报考(废话,不是这样的话,我也就不会落榜了 ̄へ ̄)。现在的问题是:对于许多考生,以及志愿信息,还有研究生院,该如何招生呢?本题给出的录取过程如下:

  • step 1:根据考生的两个分数(Ge,Gi)的平均分排名,如果排名相同,则比较Ge的分数,如果还相同,则排名相同。
  • step 2:得到考生的排名信息之后,针对其每个人的志愿进行录取。如果达到了每个院的录取限额之后便不再录取。
  • step 3:如果一个学院录取了一个排名相同的人之后,会超标,则就超标,不用担心。【这句话很关键,参见下面的英文表述】

If there is a tied rank, and if the corresponding applicants are applying to the same school, then that school must admit all the applicants with the same rank, even if its quota will be exceeded.

2.分析

其实这种模拟题还是很简单的。主要思想如下:

  • step 1:先按照要求排序
  • step 2:将排好序的学生逐个录取,看是否能够录取。这里需要注意排名相同,但是限额超标的情况(只要加个else条件即可)
  • step 3:将得到的结果放到set中,然后排序输出即可。

3.代码

#include<cstdio>
#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#define maxn 40005

using namespace std;

struct Student{
	double Ge,Gi;//标记两种成绩	  
	double avg;//平均成绩  用int存储貌似不合适
	int flag;//是否招收成功 1=成功 
	vector<int> choice;//表示每个申请者的志愿 
	int id;//初始id 
};


int cmp(Student s1,Student s2){
	if(s1.avg == s2.avg){
		return s1.Ge > s2.Ge;
	}
	return s1.avg > s2.avg;	 
}

int  N,M,K;
Student stu[maxn];

int main(){	
	cin >> N >> M >> K;
	int i,j,k;
	int quota[M];//每个学院的配额 
	vector<int> admi[M] ;//每个学院招收的学生的id 
	for(i = 0;i< M;i++){
		cin >> quota[i];
	}	
	int aca;//目标学院 
	for(i = 0;i< N;i++){
		cin >> stu[i].Ge >> stu[i].Gi ;
		stu[i].avg = (stu[i].Ge + stu[i].Gi) / 2;//取平均成绩 
		for(j = 0;j< K;j++){
			cin >> aca;
			stu[i].choice.push_back(aca); 
		}
		stu[i].id = i;//初始化id 
	}
	
	sort(stu,stu+N,cmp);
//	for(i = 0;i< N;i++){
//		cout << stu[i].avg << " ";
//	}
	//cout << "=====\n";

	//各个学院开始招收学生 
	for(i = 0;i< N;i++){//遍历每个学生 
		for(j = 0;j< K;j++){
			if(quota[stu[i].choice[j]] > 0){//如果每个学院还有剩余名额
			//	cout << "choice : "<< stu[i].choice[j] <<"\n";
				quota[stu[i].choice[j]] --;//名额减一
				admi[stu[i].choice[j]].push_back(i);//被该学院招收
				stu[i].flag = 1;//入学			 
				break;//跳出当前循环 
			}
			else{//如果名额已经没有了,但是最后录取的人和当前的人名次相同,则也要录取 				
				if(stu[admi[stu[i].choice[j]].back()].avg == stu[i].avg 
				&& stu[admi[stu[i].choice[j]].back()].Ge == stu[i].Ge)//vector最后一个元素 
				{
					//cout << "该学院当前的最后一名是:" << admi[stu[i].choice[j]].back() <<"\n";
					admi[stu[i].choice[j]].push_back(i);//被该学院招收
					stu[i].flag = 1;//入学			 
					break;//跳出当前循环 
				}
			} 
		}
	}

	set<int> res;
	// 输出每个学院招收的学生	
	for(i = 0;i < M;i++){
		for(j = 0;j< admi[i].size();j++){
			res.insert(stu[admi[i][j]].id);
			//cout << stu[admi[i][j]].id << " ";				
		}
		set<int> :: iterator temp ;
		for(set<int> ::iterator it = res.begin();it!=res.end();it++){
			temp = it;
			if(++temp != res.end()) cout << *it << " ";
			else cout << *it ;
		}
		res.clear();//清空 
		cout <<"\n";
	}	
} 

4.测试用例

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

5.执行结果

在这里插入图片描述

6.其它

这里用到了几个知识:

  • 使用double 存储成绩
  • 使用vector.back()取vector最后的一个元素

猜你喜欢

转载自blog.csdn.net/liu16659/article/details/89504394