1
题目大意:

有N位考生,M所学校,每位考生都有K个志愿学校,每个学校也有招生人数限制。现在给出所有考生的初试成绩GE、面试成绩GI以及K个志愿学校的编号,要求模拟学校录取招生的过程,并输出每个学校录取的考生编号(按从小到大顺序)。

排序规则:
先按考生的总分(GE + GD)/2从高到低排序,总分相同的按GE从高到低排序。如果GE仍然相同,则按排名相同处理。 
算法思路:

首先得定义好数据的结构,方便处理,这里采用结构体Applicant保存每一位考生的id,GE,GI,总分,排名和志愿信息,并且使用数组vector<Applicant> schools[M]记录每一个学校录取的学生,这里对于总分直接采用GE+GI的处理,无需除以2。依次将所有数据进行输入后,对所有的学生进行排序,然后获取排名,再按照排名的顺序遍历每一个学生的每一个志愿,只要当前填写的志愿学校没有招满或者最后一个学生的排名等于当前学生的排名就可以录取,这里得注意录取后得退出循环不得在进行处理。最后按照要求输出,得注意每一个学校录取的考生的编号是按照从小到大进行输出的。

提交结果:

截屏2020-09-30 下午1.49.58.png

AC代码:
#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

struct Applicant{
    int id;
    int GE;
    int GI;
    int final_grade;
    int rank;
    int preferred_schools[6];
};

bool cmp(Applicant a,Applicant b){
    if (a.final_grade!=b.final_grade){
        return a.final_grade>b.final_grade;
    } else {
        return a.GE>b.GE;
    }
}

bool cmpById(Applicant a,Applicant b){
    return a.id<b.id;
}

int main(){
    int N,M,K;// 总人数,学校数目,每一个学生的志愿数目
    scanf("%d %d %d",&N,&M,&K);
    int quota[M];// 每一个学校的名额
    for (int i = 0; i < M; ++i) {
        scanf("%d",&quota[i]);
    }
    vector<Applicant> applicants;// 保存所有学生
    Applicant applicant;
    for (int j = 0; j < N; ++j) {
        scanf("%d %d",&applicant.GE,&applicant.GI);
        applicant.final_grade = applicant.GE+applicant.GI;
        applicant.id = j;
        for (int i = 0; i < K; ++i) {
            scanf("%d",&applicant.preferred_schools[i]);
        }
        applicants.push_back(applicant);
    }
    sort(applicants.begin(),applicants.end(),cmp);
    // 获取排名
    for (int k = 0; k < applicants.size(); ++k) {
        if(k==0){
            applicants[k].rank = 1;
        } else if (applicants[k].final_grade==applicants[k-1].final_grade&&applicants[k].GE==applicants[k-1].GE){
            applicants[k].rank = applicants[k-1].rank;
        } else {
            applicants[k].rank = k+1;
        }
    }
    vector<Applicant> schools[M];// 每一个学校录取的学生
    // 处理每一个考生的志愿
    for (int l = 0; l < applicants.size(); ++l) {
        // 遍历所有的志愿
        for (int i = 0; i < K; ++i) {
            int preferred = applicants[l].preferred_schools[i];
            // 首先判断该学校是否招满了
            if(schools[preferred].size()<quota[preferred]||schools[preferred][schools[preferred].size()-1].rank==applicants[l].rank){
                // 没有满,直接招或学校招满了,但是该学生和最后一名排名相同,也招
                schools[preferred].push_back(applicants[l]);
                break;
            } 
        }
    }
    for (int m = 0; m < M; ++m) {
        // 招到学生才进行处理
        if (schools[m].size()>0){
            sort(schools[m].begin(),schools[m].end(),cmpById);
            for (int i = 0; i < schools[m].size(); ++i) {
                printf("%d",schools[m][i].id);
                if (i<schools[m].size()-1) printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}


乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得