PAT(A) 1080 Graduate Admission(满分30)

题目翻译:
据说,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甲级的题目。
该睡了,明天开始,还是从简单题目入手吧!

猜你喜欢

转载自blog.csdn.net/qq_27538633/article/details/105721957