首先,先贴柳神的博客
想要刷好PTA,强烈推荐柳神的博客,和算法笔记
It is said that in 2011, there are 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:
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 *G**E* and *G**I, 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.
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.
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
0 10
3
5 6 7
2 8
1 4
Graduate 研究生
Admission 录用
entrance exam grade 入学考试成绩
interview grade 面试成绩
给你N个学生,然后给考试成绩和面试成绩,在给M个学校
这M个学校他们收的人都不同,每个学生最多可以报K个学校
① M个学校收入是按照成绩好坏来排的,先是按照考试成绩和面试成绩的平均分,如果考试成绩和面试成绩相同的话,在优先录取按照考试成绩高的
② 如果有人的平均分和考试成绩都一样的话,学校可以破格都录取
③ 最后一行是一定要多输出的,PTA的格式问题,都搞不清楚的我.
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct student {
int grade[3];
vector<int>choice;
int rank;
int id;
};
struct School {
vector<int> people;
int last; //记录上一次的分数
int Max;
};
bool cmp(student a, student b) {
if (a.grade[2] != b.grade[2]) return a.grade[2] > b.grade[2];
else
return a.grade[0] > b.grade[0];
}
int main(void) {
int N, M, K;
scanf("%d%d%d", &N, &M, &K);
vector<School> Sch(M);
vector<student> data(N);
for (int i = 0; i < M; i++) scanf("%d", &Sch[i].Max);
for (int i = 0; i < N; i++) {
int t;
scanf("%d%d", &data[i].grade[0], &data[i].grade[1]);
data[i].grade[2] = data[i].grade[0] + data[i].grade[1];
for (int j = 0; j < K; j++) {
scanf("%d", &t);
data[i].choice.push_back(t);
}
}
for (int i = 0; i < N; i++) data[i].id = i;
sort(data.begin(), data.end(), cmp);
data[0].rank = 1;
for (int i = 1; i < N; i++) {
if (data[i].grade[2] == data[i - 1].grade[2] && data[i].grade[0] == data[i - 1].grade[0]) {
data[i].rank = data[i - 1].rank;
}
else
data[i].rank = i + 1;
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < K; j++) {
if (Sch[data[i].choice[j]].Max > 0) {
Sch[data[i].choice[j]].Max--;
Sch[data[i].choice[j]].people.push_back(data[i].id); //把这个人放进去
Sch[data[i].choice[j]].last = data[i].rank;
break;
}
else {
if (data[i].rank <= Sch[data[i].choice[j]].last) {
Sch[data[i].choice[j]].people.push_back(data[i].id); //把这个人放进去
Sch[data[i].choice[j]].last = data[i].rank;
break;
}
}
}
}
for (int i = 0; i < M; i++) {
sort(Sch[i].people.begin(), Sch[i].people.end());
for (auto it = Sch[i].people.begin(); it != Sch[i].people.end(); it++) {
if (it != Sch[i].people.begin()) {
printf(" ");
}
printf("%d", *it);
}
printf("\n");
}
return 0;
}
分析:
1.stu容器里放学生{id, ge, gi, fin, choice(容器里放学生报考学校的id)}, quota数组放招生计划的数量,cnt数组存放当前学校已经招收的学生数,sch数组里放的容器,容器里是学校已经招的学生的id~
2.对学生按照分数排序,依次学生遍历,分数最高的学生先挑学校~
3.对于每个学生录取到哪里:依次遍历学生的报考志愿,如果(没招满 || 他与已经招的学生的最后一名成绩并列)就把他招进去,该学生录取结果即可确定,更新该学校已经招生的人数,并把次学生加入该学校录取容器中~
4.输出学校录取情况时学生id顺序是乱的,要先从小到大排序,然后输出。每个学校占一行~
5.排序函数要用 & 引用传参,不然会超时~
6.因为分数 fin = ge + gi 不会超出int, fin / 2 和fin排名效果一样, 不除2不会影响结果,而且还可以巧妙躲避除2后double不能精确表示的问题~
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct peo {
int id, ge, gi, fin;
vector<int> choice;
};
bool cmp(peo& a, peo& b) {
if (a.fin != b.fin) return a.fin > b.fin;
return a.ge > b.ge;
}
bool cmp2(peo& a, peo& b) {
return a.id < b.id;
}
int main() {
//quota,就是学校的人数
int n, m, k, quota[110], cnt[110] = { 0 };
scanf("%d%d%d", &n, &m, &k);
vector<peo> stu(n), sch[110];
for (int i = 0; i < m; i++)
scanf("%d", "a[i]);
for (int i = 0; i < n; i++) {
scanf("%d%d", &stu[i].ge, &stu[i].gi);
stu[i].id = i; //这一步我还用了一个循环
stu[i].fin = stu[i].ge + stu[i].gi;
stu[i].choice.resize(k); //分配了一个这么大的空间
for (int j = 0; j < k; j++)
scanf("%d", &stu[i].choice[j]);
}
sort(stu.begin(), stu.end(), cmp);
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
int schid = stu[i].choice[j];
int lastindex = cnt[schid] - 1;
if (cnt[schid] < quota[schid] || (stu[i].fin == sch[schid][lastindex].fin) && stu[i].ge == sch[schid][lastindex].ge) {
sch[schid].push_back(stu[i]);
cnt[schid]++;
break;
}
}
}
for (int i = 0; i < m; i++) {
sort(sch[i].begin(), sch[i].end(), cmp2);
for (int j = 0; j < cnt[i]; j++) {
if (j != 0) printf(" ");
printf("%d", sch[i][j].id);
}
printf("\n");
}
return 0;
}
① 柳神用了cnt来保存学校招的人,这样就可以不用多判断
② 柳神没有搞那个rank,而我搞了,后来想想也是可以不用的
PTA甲级1080 Graduate Admission (30point(s))
原文:https://www.cnblogs.com/a-small-Trainee/p/12457955.html