【PAT】1080 Graduate Admission (30 分)

46 篇文章 0 订阅
44 篇文章 0 订阅
  • 题目大意:根据考生的成绩和填报志愿录取考生。

    1. final_grade = (ge + gi)/2,按 final_grade排名,若final_grade相同,就看ge,若都相同,就说明排名相同。;
    2. 每个学生有k个志愿选择,如果按照排名这个人可以录取,且志愿学校还有名额,就录取该学生到这个学校;若该学校名额已满,但是该校最后一个录取的人的排名和当前人排名相同,该校也要录取这个人。
  • 思路:

    1. 用结构体数组stu存学生信息,用数组quota存每个学校的名额,用数组存每个学校当前已录取的学生个数,用二维数组存每个学校录取学生的id;
    2. 给学生的成绩排序:按 final_grade排名,若final_grade相同,就看ge(final_grade可以用ge + gi表示,不会影响排名);
    3. 录取时,若学校名额已满,但当前学生的成绩和这个学校最后一个学生的成绩一样(final和ge都相等),也要将当前学生录取
    4. 输出学校的学生时,要给学生的id排名。
  • 知识点:

    1. struct
    2. vector
      1. vector<int> a[10]:二维数组
      2. v.resize(k):给v重新定义大小
    3. hash:用cnt[i]存每个学校录取了的学生个数
    4. sort
  • 代码:

    #include <iostream>
    #include <vector>
    #include <algorithm>
    using namespace std;
    
    struct applicant{
        int id, ge, gi, final;
        vector<int> choices;
    };
    
    bool cmp(applicant& a, applicant& b){
        return a.final == b.final ? a.ge > b.ge : a.final > b.final;
    }
    
    bool cmp1(applicant& a, applicant& b){
        return a.id < b.id;
    }
    
    int main(){
        int n, m, k, i, j;
        scanf("%d %d %d", &n, &m, &k);
        vector<applicant> stu(n), sch[101];
        int quota[101] = {0}, cnt[101] = {0};
    
        for(i = 0; i < m; i++)
            scanf("%d", quota + i);
    
        for(i = 0; i < n; i++){
            scanf("%d %d", &stu[i].ge, &stu[i].gi);
            stu[i].id = i;
            stu[i].final = stu[i].ge + stu[i].gi;
            stu[i].choices.resize(k);
            for(j = 0; j < k; j++)
                scanf("%d", &stu[i].choices[j]);
        }
    
        sort(stu.begin(), stu.end(), cmp);
        for(i = 0; i < n; i++){
            for(j = 0; j < k; j++){
                int schid = stu[i].choices[j];
                int pre = cnt[schid] - 1;
                if(cnt[schid] < quota[schid] || (sch[schid][pre].final == stu[i].final && sch[schid][pre].ge == stu[i].ge)){
                    sch[schid].push_back(stu[i]);
                    cnt[schid]++;
                    break;  // 录取了这个学校就不用考虑后面的学校了
                }
            }
        }
    
        for(i = 0; i < m; i++){ // 学校个数是m,不是k
            sort(sch[i].begin(), sch[i].end(), cmp1);
            for(auto it = sch[i].begin(); it != sch[i].end(); it++) {
                if(it != sch[i].begin())
                    printf(" ");
                printf("%d", (*it).id);
            }
            printf("\n");
        }
        return 0;
    }
    
    
  • 总结:

    1. 遇到这种比较麻烦的模拟题(也许是?)就不会做,思路很乱。但是跟着柳诺大神理清思路一点一点来,思路就清晰了;

    2. 以后可以用多个容器来存一样物品的多个信息,比如这里学校的信息就用了三个容器:

      1. vector<applicant> sch[101];:存学校里面的学生信息
      2. int quota[101] = {0};:存学校的招生指标
      3. int cnt[101] = {0};:存学校当前录取的学生数

      这样思路清晰、操作方便

    3. v.resize(k)给v重新定义大小后,可以直接输入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值