个人练习-PAT-1080 Graduate Admission

题目链接https://pintia.cn/problem-sets/994805342720868352/problems/994805388447170560

明天考试,死亡冲锋。。
题目就是浙江高考志愿投档,设计好学校和学生的结构体(类)之后就比较清晰。因为输出每个学校录取的学生编号时需要非递减排序,所以干脆用一个vector<bool> adm(N)数组来表示某个学生是否被录取了,另外用一个num来存该学校录取了多少学生。last_r表示该学校录取的最后一名学生的排名。

class School {
public:
    int quota, last_r, num;
    vector<bool> adm;
};

class Student {
public:
    int id, ge, gi, rank;
    double gf;
};

在排名过程中,得出一位学生的排名后就可以对其进行志愿投档了,写在同一个循环里。注意投档时idx表示学生编号,而stu[i].rank则表示这位学生的排名,stu[i].id==idx,搞清楚这两个下标的含义。

    for (int i = 0; i < N; i++) {
        if (i == 0)
            stu[0].rank = 1;
        else {
            if (stu[i].gf == stu[i - 1].gf && stu[i].ge == stu[i - 1].ge)
                stu[i].rank = stu[i - 1].rank;
            else
                stu[i].rank = i + 1;
        }

        int idx = stu[i].id;
        for (int j = 0; j < K; j++) {
            if (sch[prf[idx][j]].quota > 0) {
                sch[prf[idx][j]].adm[idx] = true;
                sch[prf[idx][j]].last_r = stu[i].rank;
                sch[prf[idx][j]].quota--;
                sch[prf[idx][j]].num++;
                break;
            }
            else {
                if (sch[prf[idx][j]].last_r == stu[i].rank) {
                    sch[prf[idx][j]].adm[idx] = true;
                    sch[prf[idx][j]].num++;
                    break;
                }
            }

        }
    }

完整代码

#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<map>
#include<set>
#include<queue>
#include<string.h>

using namespace std;

class Student {
public:
    int id, ge, gi, rank;
    double gf;
};

class School {
public:
    int quota, last_r, num;
    vector<bool> adm;
};

bool cmp(Student x, Student y) {
    if (x.gf != y.gf)
        return x.gf > y.gf;
    else
        return x.ge > y.ge;
}

void Init(vector<School>& sch, int M, int N) {
    for (int i = 0; i < M; i++) {
        sch[i].num = 0;
        sch[i].adm.resize(N, false);
    }
}

int main() {
    int N, M, K;
    scanf("%d %d %d", &N, &M, &K);
    vector<School> sch(M);
    vector<Student> stu(N);
    vector<vector<int>> prf(N, vector<int>(K));

    Init(sch, M, N);

    for (int i = 0; i < M; i++)
        scanf("%d", &sch[i].quota);

    for (int i = 0; i < N; i++) {
        stu[i].id = i;
        int ge, gi;
        scanf("%d %d", &stu[i].ge, &stu[i].gi);
        stu[i].gf = 1.0 * (stu[i].ge + stu[i].gi) / 2.0;
        for (int j = 0; j < K; j++)
            scanf("%d", &prf[i][j]);
    }

    sort(stu.begin(), stu.end(), cmp);
    
    for (int i = 0; i < N; i++) {
        if (i == 0)
            stu[0].rank = 1;
        else {
            if (stu[i].gf == stu[i - 1].gf && stu[i].ge == stu[i - 1].ge)
                stu[i].rank = stu[i - 1].rank;
            else
                stu[i].rank = i + 1;
        }

        int idx = stu[i].id;
        for (int j = 0; j < K; j++) {
            if (sch[prf[idx][j]].quota > 0) {
                sch[prf[idx][j]].adm[idx] = true;
                sch[prf[idx][j]].last_r = stu[i].rank;
                sch[prf[idx][j]].quota--;
                sch[prf[idx][j]].num++;
                break;
            }
            else {
                if (sch[prf[idx][j]].last_r == stu[i].rank) {
                    sch[prf[idx][j]].adm[idx] = true;
                    sch[prf[idx][j]].num++;
                    break;
                }
            }

        }
    }


    for (int i = 0; i < M; i++) {
        bool flag = true;
        if (sch[i].num > 0) {
            for (int j = 0; j < sch[i].adm.size(); j++) {
                if (sch[i].adm[j]) {
                    if (flag) {
                        flag = false;
                        printf("%d", j);
                    }
                    else 
                        printf(" %d", j);
                }
            }
        }
        else;
        printf("\n");
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值