PAT 1080. Graduate Admission (30)

算法思想:首先对所有学生按成绩排序,然后依次放入各个学校(过程中注意是否排名和该学校最后一名一样)

算法的主要步骤如下:

首先,根据申请者的总分和 GE 分数对申请者列表进行排序,将总分高的申请者排在前面,如果总分相同,则将 GE 分数高的申请者排在前面。

排名索引的计算:遍历排序后的申请者列表,如果当前申请者的分数和排名与上一个申请者相同,则将当前申请者的排名索引设为与上一个申请者相同;否则,将当前申请者的排名索引设为当前遍历的位置。

接下来,遍历申请者列表,对每个申请者的偏好学校进行遍历。对于每个偏好学校,检查学校的容量是否还有余量。如果有余量,则将该申请者加入学校的录取学生列表,并跳出内层循环,继续处理下一个申请者。

如果学校容量已满,但最后一个被录取的学生与当前申请者具有相同的排名索引,也将该申请者加入学校的录取学生列表,并跳出内层循环。

最后,按学校的索引顺序打印出每个学校录取的学生列表,其中学生按照其索引进行排序。

该算法通过排序和遍历的方式,按照一定的优先级和条件将申请者分配到学校中,以实现合理的录取结果。

#include 
#include 
#include 

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;
}

你可能感兴趣的:(数据结构,算法)