【PAT】A1080. Graduate Admission(排序,现实模拟)

【PAT】A1080. Graduate Admission(排序,现实模拟)

@(PAT)

链接:https://www.patest.cn/contests/pat-a-practise/1080

思路:
1. 其实主要是理解并处理好题目所说的录取的规则。用一个结构体存储好信息后,使用sort进行排序,然后根据录取的规则进行排名。
2. 排名完后根据录取的规则,排名从前往后一个学生一个学生进行录取,顺序遍历他们的志愿,如果没满就直接录取,如果满了,就要使用最后一条规则。如果学校满人了,但是这个人的成绩和刚好这个学校录取满的最后一个人的排名相同的话,也是能够录取的。这里注意到录取后要break停止志愿的循环,不然就重复了。

My AC code:

#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

#include <cstdio>
#include <cstring>
#include <cstdlib>

using namespace std;

struct Student {
    int id;
    int ge;
    int gi;
    int gtotal;
    int prefer[6];
    int rank;
};

bool cmp(Student s1, Student s2) {
    if (s1.gtotal!= s2.gtotal) return s1.gtotal> s2.gtotal;
    return s1.ge > s2.ge;
}

bool cmp1(Student s1, Student s2) {
    return s1.id < s2.id;
}

int main() {
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    vector<int> quota;
    vector<Student> students;
    vector< vector<Student> > schools;
    for (int i = 0; i < m; i++) {
        int temp;
        scanf("%d", &temp);
        quota.push_back(temp);
        vector<Student> school;
        schools.push_back(school);
    }
    for (int i = 0; i < n; i++) {
        Student s;
        s.id = i;
        scanf("%d%d", &s.ge, &s.gi);
        for (int j = 0; j < k; j++) {
            scanf("%d", &s.prefer[j]);
        }
        s.gtotal = s.ge + s.gi;
        students.push_back(s);
    }
    sort(students.begin(), students.end(), cmp);
    int rank = 1;
    for (int i = 0; i < n; i++) {
        if (i != 0) {
            if (students[i].gtotal < students[i - 1].gtotal) {
                rank = i + 1;
            }
            else if (students[i].gtotal == students[i - 1].gtotal) {
                if (students[i].ge < students[i - 1].ge) {
                    rank = i + 1;
                }
            }
        }
        students[i].rank = rank;
    }
    vector<bool> finished;
    for (int i = 0; i < m; i++) {
        finished.push_back(false);
    }
    for (int i = 0; i < n; i++) {
        int prefer_school;
        bool if_admit = false;
        for (int j = 0; j < k; j++) {
            prefer_school = students[i].prefer[j];
            if (!finished[prefer_school]) {
                if (schools[prefer_school].size() <quota[prefer_school]) {
                    schools[prefer_school].push_back(students[i]);
                    if_admit = true;
                    break;
                }
                else {
                    if (students[i].rank == schools[prefer_school][quota[prefer_school] - 1].rank) {
                        schools[prefer_school].push_back(students[i]);
                        if_admit = true;
                        break;
                    }
                    else {
                        finished[prefer_school] = true;
                    }
                }
            }
        }
    }
    for (int i = 0; i < m; i++) {
        sort(schools[i].begin(), schools[i].end(), cmp1);
        for (int j = 0; j < schools[i].size(); j++) {
            if (j == schools[i].size() - 1) {
                printf("%d", schools[i][j].id);
            }
            else {
                printf("%d ", schools[i][j].id);
            }
        }
        printf("\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值