算法思想:首先对所有学生按成绩排序,然后依次放入各个学校(过程中注意是否排名和该学校最后一名一样)
算法的主要步骤如下:
首先,根据申请者的总分和 GE 分数对申请者列表进行排序,将总分高的申请者排在前面,如果总分相同,则将 GE 分数高的申请者排在前面。
排名索引的计算:遍历排序后的申请者列表,如果当前申请者的分数和排名与上一个申请者相同,则将当前申请者的排名索引设为与上一个申请者相同;否则,将当前申请者的排名索引设为当前遍历的位置。
接下来,遍历申请者列表,对每个申请者的偏好学校进行遍历。对于每个偏好学校,检查学校的容量是否还有余量。如果有余量,则将该申请者加入学校的录取学生列表,并跳出内层循环,继续处理下一个申请者。
如果学校容量已满,但最后一个被录取的学生与当前申请者具有相同的排名索引,也将该申请者加入学校的录取学生列表,并跳出内层循环。
最后,按学校的索引顺序打印出每个学校录取的学生列表,其中学生按照其索引进行排序。
该算法通过排序和遍历的方式,按照一定的优先级和条件将申请者分配到学校中,以实现合理的录取结果。
#include <iostream>
#include <vector>
#include <algorithm>
struct Applicant {
int ge; // GE 分数
int gi; // GI 分数
std::vector<int> preferred_schools; // 偏好的学校列表
int index; // 学生索引
float grade = 0; // 平均分数
int rank_index; // 排名索引
};
struct School {
int capacity = 0; // 学校容量
std::vector<Applicant> admitted_students; // 录取的学生列表
};
bool compareApplicants(const Applicant& a, const Applicant& b) {
// 根据总分排序
if (a.ge + a.gi != b.ge + b.gi) {
return (a.ge + a.gi) > (b.ge + b.gi);
} else {
// 总分相同,则根据 GE 分数排序
return a.ge > b.ge;
}
}
int main() {
int N, M, K;
std::cin >> N >> M >> K; // 输入申请者人数、学校数量和每个申请者的偏好学校数量
std::vector<School> schools(M); // 创建学校列表
std::vector<Applicant> applicants(N); // 创建申请者列表
for (int i = 0; i < M; i++) {
std::cin >> schools[i].capacity; // 输入每个学校的容量
}
for (int i = 0; i < N; i++) {
applicants[i].index = i; // 设置申请者的索引
std::cin >> applicants[i].ge >> applicants[i].gi; // 输入申请者的 GE 和 GI 分数
applicants[i].grade = (applicants[i].ge + applicants[i].gi) / 2.0; // 计算平均分数
applicants[i].preferred_schools.resize(K); // 调整偏好学校列表的大小
for (int j = 0; j < K; j++) {
std::cin >> applicants[i].preferred_schools[j]; // 输入申请者的偏好学校
}
}
// 对申请者进行排名
std::sort(applicants.begin(), applicants.end(), compareApplicants);
for (int i = 0; i < applicants.size(); i++) {
if (i > 1 && applicants[i].grade == applicants[i - 1].grade &&
applicants[i].ge == applicants[i - 1].ge) {
applicants[i].rank_index = applicants[i - 1].rank_index; // 相同分数和排名的申请者设置相同的排名索引
} else {
applicants[i].rank_index = i; // 设置排名索引
}
}
// 分配录取结果
for (int i = 0; i < applicants.size(); ++i) {
for (int j = 0; j < applicants[i].preferred_schools.size(); ++j) {
int school_id = applicants[i].preferred_schools[j]; // 获取偏好学校的索引
if (schools[school_id].capacity > schools[school_id].admitted_students.size()) {
schools[school_id].admitted_students.push_back(applicants[i]);
break;
}else if (schools[school_id].admitted_students.back().rank_index == applicants[i].rank_index) {
schools[school_id].admitted_students.push_back(applicants[i]);
break;
}
}
}
// 打印出录取结果
for (int i = 0; i < M; i++) {
std::sort(schools[i].admitted_students.begin(), schools[i].admitted_students.end(),
[](const Applicant& a, const Applicant& b) {
return a.index < b.index;
});
for (int j = 0; j < schools[i].admitted_students.size(); j++) {
std::cout << schools[i].admitted_students[j].index;
if (j < schools[i].admitted_students.size() - 1) {
std::cout << " ";
}
}
std::cout << std::endl;
}
return 0;
}