PAT A1080 Graduate Admission ——松下茅亭五月凉,汀沙云树晚苍苍

PAT A1080 Graduate Admission

  • 根据分数进行排名,再根据志愿学校依次录取,如果有与学校录取的最后一名排名相同且志愿相同的学生,都要一并录取,保证公平,即使已经没有名额(还好没说保护一志愿)
  • 那么顺着题意将输入放入学生数组,另搞了一个rank数组保存学生ID,之后根据学生分数排序rank数组(多弄了一个rank是因为写到录取的时候,判断如果没有名额了,就去看看被录取的最后一名跟我是不是一个水平,如果是的话,他能上那我也能上。而录取数组里存的是学生的原始ID,如果这时候学生数组被排序了,则不能根据原始ID直接定位)
  • rank排好之后一个个拿出来去申请录取,注意如果申请成功则需break,否则就可能脚踏几条船咯
  • 在这里插入图片描述
#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

struct School{
    int quota;
    vector<int> admit;
};
vector<School> vs;
struct Student{
    int idx;
    int GE,GI,GF;
    vector<int> prefer;
    int rank;
};
vector<Student> vst;
vector<int> rank_;

bool cmp(int s1,int s2){
    return vst[s1].GF != vst[s2].GF ? vst[s1].GF > vst[s2].GF : vst[s1].GE > vst[s2].GE;
}

bool applicate(int stid,int sid){
    if(vs[sid].quota > 0){
        vs[sid].admit.push_back(stid);
        vs[sid].quota --;
        return true;
    }else{
        int id = vs[sid].admit[vs[sid].admit.size() - 1];
        if(vst[id].GF == vst[stid].GF && vst[id].GE == vst[stid].GE){
            vs[sid].admit.push_back(stid);
            return true;
        }
    }
    return false;
}

int main(){

    int N,M,K;
    cin >> N >> M >> K;
    vs.resize(M);
    vst.resize(N);
    rank_.resize(N);
    for(int i = 0;i < M;i ++) cin >> vs[i].quota;
    for(int i = 0;i < N;i ++){
        vst[i].idx = i;
        rank_[i] = i;
        cin >> vst[i].GE >> vst[i].GI;
        vst[i].GF = vst[i].GE + vst[i].GI;
        for(int j = 0;j < K;j ++){
            int tmp;
            cin >> tmp;
            vst[i].prefer.push_back(tmp);
        }
    }
    sort(rank_.begin(),rank_.end(),cmp);
    for(int i = 0;i < rank_.size();i ++){
        int stid = rank_[i];
        for(int j = 0;j < vst[stid].prefer.size();j ++)
            if(applicate(stid,vst[stid].prefer[j])) break;
    }
    for(int i = 0;i < M;i ++){
        sort(vs[i].admit.begin(),vs[i].admit.end());
        for(int j = 0;j < vs[i].admit.size();j ++){
            cout << vs[i].admit[j];
            if(j < vs[i].admit.size() - 1) cout << ' ';
        }
        cout << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值