PTA_PAT甲级_1080 Graduate Admission (30分)

It is said that in 2011, there are about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.

Each applicant will have to provide two grades: the national entrance exam grade GE​​ , and the interview grade G​I. The final grade of an applicant is (G​E +GI)/2. The admission rules are:

The applicants are ranked according to their final grades, and will be admitted one by one from the top of the rank list.

If there is a tied final grade, the applicants will be ranked according to their national entrance exam grade G​E. If still tied, their ranks must be the same.

Each applicant may have K choices and the admission will be done according to his/her choices: if according to the rank list, it is one’s turn to be admitted; and if the quota of one’s most preferred shcool is not exceeded, then one will be admitted to this school, or one’s other choices will be considered one by one in order. If one gets rejected by all of preferred schools, then this unfortunate applicant will be rejected.

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.

Input Specification:
Each input file contains one test case.

Each case starts with a line containing three positive integers: N (≤40,000), the total number of applicants; M (≤100), the total number of graduate schools; and K (≤5), the number of choices an applicant may have.

In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.

Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant’s GE​​ and G​I, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M−1, and the applicants are numbered from 0 to N−1.

Output Specification:
For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants’ numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.

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

题意:
给出若干学生的初试和面试成绩,按二者之和排名,若总分一样则按初试排名,初试也一样则并列,按名次录取,每个学校有一定录取名额,每个学生有若干志愿,依次检查其志愿学校,若没录满则录取,若其所有志愿学校都录满则该生落榜,若几名考生名次并列,则即使已录满也要同时录取这几名考生,输出每个学校的录取结果

分析:
用两个结构体分别存储每个考生和学校的信息,排序,注意并列的情况

代码:

#include
#include
#include
using namespace std;

struct Student{
	int GE, GI, sum;
	int r, stuID;
	int cho[6];
}stu[40010];

struct School{
	int quato;//招生人数总额度
	int stuNum;//当前实际招生人数
	int id[40010];//招收的学生编号
	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;//总分相同按GE排序 
}

bool cmpID(int a,int b){
	return stu[a].stuID<stu[b].stuID;//考生编号按从小到大排序 
} 

int main()
{
    int N, M, K;
	cin>>N>>M>>K;
	for(int i=0;i<M;i++){//初始化每个学校 
		cin>>sch[i].quato;//招生人数额度 
		sch[i].stuNum = 0;//当前招生人数
		sch[i].lastAdmit = -1;//最后一个招生学生编号,-1表示不存在 
	} 
	for(int i=0;i<N;i++){//初始化每个学生 
		stu[i].stuID = i;
		cin>>stu[i].GE>>stu[i].GI;
		stu[i].sum = stu[i].GE + stu[i].GI;
		for(int j=0;j<K;j++) cin>>stu[i].cho[j];//K个可申请学校编号 
	} 
	sort(stu, stu+N, cmpStu);//给N为考生排序
	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].quato||(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++){//对M所学校 
		if(sch[i].stuNum>0){//如果有找到学生 
			sort(sch[i].id, sch[i].id+sch[i].stuNum, cmpID);//按ID排序
			for(int j=0;j<sch[i].stuNum;j++){
				cout<<stu[sch[i].id[j]].stuID;
				if(j<sch[i].stuNum-1) cout<<" ";
			} 
		}
		cout<<endl;
	}
    return 0;
}

你可能感兴趣的:(PTA_PAT,(Advanced,Level),Practice,排序,结构体)