题目翻译:
据说,2011年,浙江省约有100所研究生院准备着手处理40,000多份申请。 如果您可以编写一个程序来自动执行录取程序,那将会很有帮助。
每个申请人都必须提供两个等级:全国入学考试等级Ge和面试等级Gi。 申请人的最终成绩为(Ge + Gi)/ 2。 录取规则是:
(1).申请者将根据其最终成绩进行排名,并且将从排名列表的从高到低进行录取。
(2).如果最终成绩并列,则申请人将根据他们的全国入学考试等级Ge进行排名。 如果仍然并列,他们的排名必须相同。
(3).每个申请人可能有K个选择,并且将根据他/她的选择进行录取:如果按照排名列表,该轮到该录取了; 如果未超过某人最喜欢的学校的配额,则该人将被录取到这所学校,否则一个人的其他选择将被按顺序逐一考虑。 如果一个人被所有首选学校拒绝,那么这个不幸的申请人将被拒绝。
(4).如果排名并列,并且相应的申请人正在同一所学校申请,那么即使超过配额,该学校也必须录取所有具有相同职等的申请人。
输入要求:
每个输入文件包含一个测试用例。
每个案例都以包含三个正整数的行开头:N(≤40,000),即申请人总数; M(≤100),研究生院总数; 和K(≤5),即申请人可以选择的数量。
在下一行,由空格隔开,有M个正整数。 第i个整数分别是第i个研究生院的配额。
然后,N行跟随,每行包含2 + K个整数,并用空格分隔。 前两个整数分别是申请人的Ge和Gi。 接下来的K个整数表示首选学校, 为了简单起见,我们假设学校的编号从0到M-1,申请人的编号从0到N-1。
输出要求:
对于每个测试用例,您应该输出所有研究生院的录取结果。 每所学校的成绩必须占据一行,其中包含学校录取的申请人编号。 数字必须按升序排列,并用空格分隔。 每行的末尾必须没有多余的空格。 如果没有任何学生被学校录取,则必须相应地输出空白行。
样例输入:
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
这道题,自己思路上一开始还是没有理清楚,所以,借鉴了B站一位UP主思路。
下面的代码是自己写的,但是运行后只得了三分之一的分数,有两个测试点数据错误,错误的问题,还在寻找。先贴出来这段代码:
#include<iostream>
#include<algorithm>
#include <vector>
using namespace std;
struct student {
int id;
int ge;
int gi;
int g3;
int b[5];
};
bool cmp(student a, student b) {
if (a.g3 != b.g3)
return a.g3 > b.g3;
// else
return a.ge > b.ge;
}
bool cmpId(student a, student b) {
return a.id < b.id;
}
int main()
{
struct student *stu;
int n, m, k;
// n申请人总数,m研究生院总数,k申请人可以选择的数量
cin >> n >> m >> k;
vector<student> inschool[100];
int a[101] = { 0 }; // 每个研究生院的配额
for (int i = 0; i < m; i++)
{
int g;
cin >> g;
a[i] = g;
}
//为结构体分配存储空间
stu = (struct student *)malloc(40000* sizeof(struct student));
for (int i = 0; i < n; i++) // 为所有学生输入他的各项信息
{
stu[i].id = i;
int c, d, e;
cin >> c >> d;
stu[i].ge = c;
stu[i].gi = d;
stu[i].g3 = (c + d) / 2;
for (int j = 0; j < k; j++)
{
cin >> e;
stu[i].b[j] = e;
}
}
sort(stu, stu+n-1, cmp);
for (int i = 0; i < n; i++) {
for (int j = 0; j < k; j++) {
int want = stu[i].b[j];
if (inschool[want].size() < a[want]) {
inschool[want].push_back(stu[i]);
break;
}
else {
if (inschool[want].back().g3 == stu[i].g3 &&
inschool[want].back().ge == stu[i].ge) {
inschool[want].push_back(stu[i]);
break;
}
}
}
}
for (int i = 0; i < m; i++) {
if (inschool[i].size() == 0)
cout << endl;
else {
sort(inschool[i].begin(), inschool[i].end(), cmpId);
for (int j = 0; j < inschool[i].size(); j++) {
if (j)
cout << " ";
cout << inschool[i][j].id;
}
cout << endl;
}
}
system("pause");
return 0;
}
满分代码:来自于一个B站UP那里,也贴出来继续学习。
这位UP的B站信息
代码如下:
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct stu {
int id;
double g1, g2, g3;
int choice[5];
};
bool cmp(stu a, stu b) {
if (a.g3 != b.g3) return a.g3 > b.g3;
return a.g1 > b.g1;
}
bool cmpId(stu a, stu b) {
return a.id < b.id;
}
int main() {
int n, m, k;
scanf("%d %d %d", &n, &m, &k);
int schoolsLimit[100];
vector<stu> inschool[100];
vector<stu> students;
stu tmp;
for (int i = 0; i < m; ++i)
scanf("%d", &schoolsLimit[i]);
for (int i = 0; i < n; ++i) {
tmp.id = i;
scanf("%lf %lf", &tmp.g1, &tmp.g2);
tmp.g3 = (tmp.g1 + tmp.g2) / 2;
for (int j = 0; j < k; ++j)
scanf("%d", &tmp.choice[j]);
students.push_back(tmp);
}
sort(students.begin(), students.end(), cmp); // rank靠前的先安排
for (int i = 0; i < n; ++i) {
for (int j = 0; j < k; ++j) {
int want = students[i].choice[j];
if (inschool[want].size() < schoolsLimit[want]) { // 想去的学校还有名额
inschool[want].push_back(students[i]);
break;
}
else {
if (inschool[want].back().g3 == students[i].g3 &&
inschool[want].back().g1 == students[i].g1) {
// 没名额了 但是该考生和该校录取的最后一名高考总分相同
inschool[want].push_back(students[i]);
break;
}
}
}
}
for (int i = 0; i < m; i++) {
if (inschool[i].size() == 0)
printf("\n");
else {
sort(inschool[i].begin(), inschool[i].end(), cmpId);
for (int j = 0; j < inschool[i].size(); j++) {
if (j)
printf(" ");
printf("%d", inschool[i][j].id);
}
printf("\n");
}
}
return 0;
}
后记:自己能力还是有限,还是先去夯实基础,先把PAT乙级题目做大量以后,再回头来做PAT甲级的题目。
该睡了,明天开始,还是从简单题目入手吧!