1080 Graduate Admission

排序题,

关键是要想到排序后,是按照学生的志愿来遍历,所有志愿都拒绝了,这个学生就是reject;

所有学生都录取或reject了,就停止;

两个结构体是一边写代码时一边完善的:

typedef struct stu{
	int id;
	int ge;

	double total;
	int pre[6];//k<=5
	 short isAdmit; //0待录取, 1录取, -1所有的志愿都拒绝了
	 
};

stu stus[40000+5];

typedef struct colleage{
	int id;
	int quota;

	vector<int> admit;
	int lastAdmitStu;
};

colleage cols[100+5];
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;

int n , m, k;


typedef struct stu{
	int id;
	int ge;

	double total;
	int pre[6];//k<=5
	 short isAdmit; //0待录取, 1录取, -1所有的志愿都拒绝了
	 
};

stu stus[40000+5];

typedef struct colleage{
	int id;
	int quota;

	vector<int> admit;
	int lastAdmitStu;
};

colleage cols[100+5];

int cmp(const void * a, const void * b){
	stu sa = *(stu *)a;
	stu sb = *(stu *)b;

	if(sa.total != sb.total){
		if(sa.total > sb.total){
			return -1;
		}else{
			return 1;
		}
	} 

	return (sb.ge - sa.ge);
}

int main(){
	freopen("in.txt","r",stdin);


	scanf("%d%d%d",&n,&m,&k);

	for(int i = 0; i < m; i++){
		colleage col;
		scanf("%d" , &col.quota);
		col.id = i;
		 
		 
		col.lastAdmitStu = -1;

		cols[i] = col;
	}

	for(int i = 0; i < n; i++){
		stu s;
		s.id  = i;
		int ge, gi;
		scanf("%d %d",&ge, &gi);
		s.ge = ge;
		s.total = (ge + gi)/2.0;

		for(int j = 0; j < k; j++){
			scanf("%d", &s.pre[j]);
		}

		s.isAdmit = 0;
		 

		stus[i] = s;
	}

	qsort(stus, n, sizeof(stu), cmp);

	//test
	/*for(int i = 0; i < n; i++){
		printf("%d-st is %d\n", i, stus[i].id);
	}*/


	 
	
	bool flag;


	while(1){
		flag = true;
		for(int i = 0; i < n; i++){
			if(stus[i].isAdmit  == 0 ){//还有学生待录取

				if(flag){
					flag = false;
				}

				int currentStu = stus[i].id;
				
				int preLevel = 0;
				int preColId;
				int lastAdmitStu;

				while(preLevel < k){//在k 个志愿内 找学校
					preColId = stus[i].pre[preLevel];
					lastAdmitStu = cols[preColId].lastAdmitStu;

					if(cols[preColId].quota > 0){
						cols[preColId].admit.push_back(currentStu);//学生id
						cols[preColId].lastAdmitStu = i; //学生下标
						cols[preColId].quota--;

						stus[i].isAdmit = 1;//被录取
						break;

					}else if(stus[lastAdmitStu].total == stus[i].total
						&& stus[lastAdmitStu].ge == stus[i].ge
						){//中意的学校已经满了,但是最低分正好与自己相等,即相等的排名
						
						cols[preColId].admit.push_back(currentStu);

						stus[i].isAdmit = 1;
						break;
			
					}else{//只好再降低志愿等级
						preLevel++;
					}
				}
				if(preLevel == k){//k个志愿都没录取,reject
					stus[i].isAdmit = -1;
				}
			}
		}

		if(flag){
			break;
		}
	}

	vector<int> res;
	for(int i = 0; i < m; i++){
		res = cols[i].admit;
		sort(res.begin(), res.end());
		bool first = true;

		for(int j = 0; j < res.size(); j++){
			if(first){
				printf("%d", res[j]);
				first = false;
			}else{
				printf(" %d", res[j]);
			}
		}
		printf("\n");
	}
	

	return 0;
}




你可能感兴趣的:(1080 Graduate Admission)