【1080 30 排序】 Graduate Admission

传送门

题意

给定\(n\)个学生,每个学生有\(Ge,Gi\)两门成绩,总和为\(final\)\(m\)个学校,每个学生有\(k\)个意向学校,成绩按照\(final\)优先,\(Ge\)第二排序进行选择,如果学生成绩相同学校可以多收,否则收满位置,输出所有学校接收的学生\(id\)

数据范围

\(n\leq 40,000\)
\(m\leq 100\)
\(k\leq 5\)

题解

  • 重写结构体==运算符用来比较相等
  • 排序后依次选择
  • 如果当前人的意向和这个学校最后一个录取的相等可以不考虑人数限制录取
  • 负数转化为bool也是true

Code

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
struct node{
	int ge,gi,final,id;
	vector<int>perfer;
	bool operator < (const node t) const {
		if(final==t.final) return ge>t.ge;
		return final>t.final;
	}
	bool operator == (const node t) const {
		if(final==t.final && ge==t.ge) return 1;
		return 0;
	}
};
int main(){
	int n,m,k; cin>>n>>m>>k;
	vector<node>stu(n);
	vector<int>school[m],cnt(m);
	for(int i=0;i<m;i++) cin>>cnt[i];
	for(int i=0;i<n;i++){
		cin>>stu[i].ge>>stu[i].gi;
		stu[i].perfer.resize(k);
		for(int j=0;j<k;j++) cin>>stu[i].perfer[j];
		stu[i].id=i;
		stu[i].final=stu[i].ge+stu[i].gi;
	}
	sort(stu.begin(),stu.end());
	for(int i=0;i<n;i++)
		for(int j=0;j<k;j++){
			int idx=stu[i].perfer[j];
			if(cnt[idx]>0 || stu[school[idx].back()]==stu[i]){
				school[idx].pb(i);
				--cnt[idx];
				break;
			}
		}
	for(int i=0;i<m;i++){
		vector<int>a;
		for(int j=0;j<school[i].size();j++) a.pb(stu[school[i][j]].id);
		sort(a.begin(),a.end());
		for(int j=0;j<a.size();j++) cout<<(j>0?" ":"")<<a[j];
		cout<<endl;
	}
}
posted @ 2021-03-05 22:41  Hyx'  阅读(65)  评论(0)    收藏  举报