1080 Graduate Admission——PAT甲级练习题

It is said that in 2013, there were 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 GI. The final grade of an applicant is (GE + 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 GE. 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 GI, 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

题目大意

这道题主要是让你模拟研究生录取的过程,题目的要求主要有一下几个方面:

  1. 每个报考人员一共有三个成绩分别为:GE, GI, final,其中final = (GE + GI) / 2;
  2. 录取的时候按照成绩排名从上往下录取
  3. 成绩排名的方式为:按照final的大小由高到低排序,如果final的值相同按照GE的值由高到低排序,如果GE和final的值都相同则两人排名相同
  4. 每个报考者都有K个选择,并且录取按照每个人的报考志愿顺序进行录取,如果其报考学校没有招满他就可以被录取,如果当前报考学校招满了则按照顺序看下一个报考学校能否录取。
  5. 如果有两个人报考同一个学校,并且两个人的排名相同,则报考学校无论是否招满都要将两人录取
  6. 注意报考人员的编号未0~N - 1,报考学校的编号为0~M - 1

题目思路

  1. 我们定义一个结构体负责存储每一个报考人员的id,GE,GI,final.同时定义一个map<int, node> mirror;负责建立每个人的学号和个人信息之间的对应关系,方便在排完序之后进行查找。
  2. 定义map<int, vector<int> > addmission;建立学校编号和个人编号之间的映射关系,按照题目排序要求进行排序,对排序后的数据进行遍历。同时遍历每一个报考学生的报考学校,如果其当前报考学校没有招满,则被录取。如果其报考学校已经招满,然后就查看其报考学校录取的最后一名的成绩和当前考生的成绩是否相同,如果过两人成绩相同则录取无论当前学校是否招满
  3. 因为题目要求按照学号大小从小到达输出,但是学号存入的时候是乱序的,所以要对学号排序。

代码

#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 10;
struct node {
int Ge, Gi, Gfinal;
vector<int> addmit;
int id, rank;
bool friend operator<(node a, node b) {
if (a.Gfinal == b.Gfinal) return a.Ge > b.Ge;
return a.Gfinal > b.Gfinal;
}
}; bool vis[N];
// node persons[N];
int n, m, k; // n是报名人数, m是学校数,
vector<int> school; int main() {
scanf("%d%d%d", &n, &m, &k);
memset(vis, 0, sizeof(vis));
for (int i = 0; i < m; i++) {
int x;
scanf("%d", &x);
school.push_back(x);
}
vector<node> persons(n);
map<int, vector<int> > addmission;
map<int, node> mirror; //建立id和个人信息之间的映射关系
for (int i = 0; i < n; i++) {
int ge, gi, choices;
scanf("%d%d", &ge, &gi);
persons[i].id = i;
persons[i].Ge = ge, persons[i].Gi = gi,
persons[i].Gfinal = (ge + gi) / 2;
for (int j = 0; j < k; j++) {
scanf("%d", &choices);
persons[i].addmit.push_back(choices);
}
mirror[persons[i].id] = persons[i];
}
sort(persons.begin(), persons.end());
for (int i = 0; i < n; i++) {
auto tmp = persons[i].addmit;
if (vis[persons[i].id]) continue;
for (int j = 0; j < tmp.size(); j++) {
if (school[tmp[j]] != 0) {
school[tmp[j]]--;
vis[persons[i].id] = true;
addmission[tmp[j]].push_back(persons[i].id);
break;
}
//如果报考学校招满,则在报考学校中查找有没有和自己排名相同的人
else if (school[tmp[j]] <= 0) {
//此处可以优化,没有必要一个一个和目标院校的所有人比较排名,直接比较自己和最后一名的成绩即可
int len = addmission[tmp[j]].size();
int ite = addmission[tmp[j]][len - 1];
if (persons[i].Gfinal == mirror[ite].Gfinal &&
persons[i].Ge == mirror[ite].Ge) {
addmission[tmp[j]].push_back(persons[i].id);
vis[persons[i].id] = true;
break;
}
}
}
}
for (int i = 0; i < m; i++) {
if (addmission[i].empty())
cout << endl;
else {
sort(addmission[i].begin(), addmission[i].end());
int len = addmission[i].size();
for (int j = 0; j < len; j++) {
printf("%d", addmission[i][j]);
if (j != len - 1)
printf(" ");
else
printf("\n");
}
}
}
return 0;
}

最新文章

  1. node的核心模块path
  2. 15,SFDC 管理员篇 - 变更和部署
  3. CSS3基础03(3D②) 求粉丝
  4. GridView获取当前行
  5. git Please move or remove them before you can merge. 错误解决方案
  6. 【BZOJ】1082: [SCOI2005]栅栏(二分+dfs)
  7. [转]div里table居中的问题 Div与body顶部间隙
  8. c语言实现BMP图像转换为灰度图
  9. c 这题做了半天,虽然做好了,但是思路还是不清晰,估计让我再做一次还是比较花时间的。
  10. 【Android UI设计与开发】第17期:滑动菜单栏(二)开源项目SlidingMenu的示例
  11. JS复习第五章
  12. 字符串的n位左旋
  13. 【Android Studio安装部署系列】十三、Android studio添加和删除Module
  14. Oracle简单触发器应用
  15. prometheus杂碎
  16. Python循环文件推荐的方式,可用于读取文本最后一行或删除指定行等
  17. 使用kcptun安全代理访问服务
  18. Azure虚机磁盘容量警报(邮件提醒)
  19. IOC的实现原理—反射与工厂模式的结合
  20. DIOCP开源项目-定义自己要发送的数据结构(MyObject)

热门文章

  1. 深信服上网行为管理配置跨三层MAC识别
  2. Java复习整理 day01
  3. cloudera manager server迁移
  4. C# 如何复制(拷贝)Label控件上的文本【新方法】
  5. Codeforces Round #533 (Div. 2) C. Ayoub and Lost Array(递推)
  6. WIN7使用msg命令发送消息心得
  7. gym100923C. Por Costel and Bujor (高斯消元)
  8. 【noi 2.7_7219】复杂的整数划分问题(算法效率)
  9. hdu 5316 Magician 线段树维护最大值
  10. hdu4501——小明系列故事——买年货(多维背包)