PAT 1080. Graduate Admission (30) 模拟高考志愿录取规则

再次1A hahah

/*************************
题意:
高考选志愿。
每个人有Ge和Gi, 最终分数是Gf。 比较方式是先看Gf,再看Ge
每个人k个志愿。
每个学校有一定的名额。
1个学生如果能被录取,则按照其志愿顺序选学校。
如果学校名额满了,只能再按志愿选下一个。

如果学校要选3个人,但是刚好有2个人分数相同
并且都是第3名,则2个人同时录取。

************************/
/***********************
解题思路:
重点在于如何理解这个志愿选择。这里就提一下我解决思路吧,反正是1A嘿嘿
输入所有学生的信息后
对所有学生进行一个总排序,按照先Gf,再Ge的规则从大到小排序。
然后从第一个学生开始依次选学校。
	而这个学生从志愿顺序开始,依次判断所填学校的名额是否满了
	如果未满,则被录取,学校名额-1。
	如果满了,则检查一下自己的分数是否与 该校录取的最后一名相同
		若与最后一名相同,则他也能够被录取。
*************************/
/***********************
笔记:

*********************/
#include<iostream>
#include<stdio.h>
#include<string>
#include<vector>
#include<queue>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<stack>
#include<map>
#include<set>
#include<unordered_map>
using namespace std;
#define M 4
#define INF 0x7ffffff

struct Applican{
	int ge,gi;
	double gf;
	int id;
	int admiss[7];
};
int quota[110];

bool cmp(Applican a,Applican b){
	if(a.gf > b.gf)
		return true;
	else if(a.gf == b.gf)
		return a.ge > b.ge;
	else return false;
}
vector<int> ans[120];
vector<Applican> AllRank;
int main(){
	int n, i, j, p, m, k;
	scanf("%d%d%d",&n, &m, &k);

	for(i = 0;i < m; i++)	
		scanf("%d","a[i]);

	int ge,gi;
	double gf;
	Applican appli;
	for(i = 0;i < n; i++){
		scanf("%d%d",&ge,&gi);
		gf = (ge + gi) / 2;
		for(j = 0;j < k; j++)
			scanf("%d", &appli.admiss[j]);
		appli.ge = ge;
		appli.gi = gi;
		appli.gf = gf;
		appli.id = i;
		AllRank.push_back(appli);
	}
	sort(AllRank.begin(), AllRank.end(), cmp);
	int school;
	Applican lastappli[110];
	for(i = 0; i < AllRank.size(); i++){  //从第一名开始选学校
		appli = AllRank[i];
		for(j = 0 ;j < k; j++){  //按照志愿选
			school = appli.admiss[j];
			if(quota[school] != 0){
				ans[school].push_back(appli.id);
				quota[school]--;
				if(quota[school] == 0){
					lastappli[school] = appli; 
				}
				break;
			}
			else{  //如果申请的学校名额为0,但是自己的排名与最后一名相同,则可以录取
				if(appli.gf == lastappli[school].gf && appli.ge == lastappli[school].ge){
					ans[school].push_back(appli.id);
					break;
				}
			}
		}

	}
	for(i = 0;i < m; i++){
		sort(ans[i].begin(), ans[i].end());
		for(j = 0;j < ans[i].size();j++){
			if(j == 0)
				printf("%d", ans[i][j]);
			else printf(" %d", ans[i][j]);
		}
		cout<<endl;
	}

	return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值