1080 Graduate Admission

题目 

题意:每个考生有两个成绩:GE和GI,最终成绩为(GE + GI) / 2;按照最终成绩排名,如果最终成绩相同,就按照GE排名,如果仍然相同,他们的排名就是相同的。每个申请者有K个选择院校,每个学校也有招生人数限制。按照排名先后,如果当前考生的第一个志愿学校的名额还没满,就录取进去;如果当前志愿名额满了但是该校最后一个录取的人的排名和当前考生相同,则不管招生人数限制,依旧应该被录取;否则考虑该生的下一个志愿。如果所有志愿都没有能被录取,则该生落榜。

tip:map+sort

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
struct ss {
	int num,Ge,Gi;
	double final_grade;
	vector<int> quato;
	int rank;
	bool admited=false;
};
bool cmp(struct ss a,struct ss b) {
	if(a.final_grade==b.final_grade)
		return a.Ge>b.Ge;
	return a.final_grade>b.final_grade;
}
int main() {
	int n,m,k;
	cin>>n>>m>>k;
	int school[m];
	for(int i=0; i<m; ++i)
		cin>>school[i];
	struct ss s[n];
	for(int i=0; i<n; ++i) {
		s[i].num=i;
		cin>>s[i].Ge>>s[i].Gi;//两种成绩
		s[i].final_grade=(s[i].Ge+s[i].Gi)/2.;//总分
		for(int j=0; j<k; ++j) {
			int t;
			cin>>t;
			s[i].quato.push_back(t);//志愿学校
		}
	}
	sort(s,s+n,cmp);
	s[0].rank=1;
	for(int i=1; i<n; ++i) {
		if(s[i].final_grade==s[i-1].final_grade&&s[i].Ge==s[i-1].Ge)
			s[i].rank=s[i-1].rank;
		else s[i].rank=i+1;
	}
	vector<vector<int>> admitted(m);//录取名单
	for(int i=0; i<n; ++i) {
		if(!s[i].admited) {//没被录取的人进入录取工作
			for(int j=0; j<s[i].quato.size(); ++j)
				if(school[s[i].quato[j]]>0) { //当前最期许的学校有名额
					admitted[s[i].quato[j]].push_back(s[i].num);
					school[s[i].quato[j]]--;
					s[i].admited=true;
					int t=s[i].quato[j];
					while(i<n-1&&s[i].rank==s[i+1].rank) {
						for(int l=0; l<s[i+1].quato.size(); ++l)
							if(school[s[i+1].quato[l]]>0&&t!=s[i+1].quato[l]) {
								break;//排名相同者,但是后者与前者可选择院校不一样时,跳过
							} else if(t==s[i+1].quato[l]) {//排名相同者,且可选择的院校相同者都得录取
								admitted[t].push_back(s[i+1].num);
								school[t]--;
								s[i+1].admited=true;
								break;
							}
						++i;
					}
					break;
				}
		}
	}
	for(int i=0; i<m; ++i) {
		sort(admitted[i].begin(),admitted[i].end());
		if(admitted[i].size())
			cout<<admitted[i][0];
		for(int j=1; j<admitted[i].size(); ++j)
			cout<<" "<<admitted[i][j];
		cout<<endl;
	}
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大章鱼(张文哲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值