PAT甲级

1080 Graduate Admission (30 分)

2019-06-08  本文已影响0人  zju_dream

1080 Graduate Admission 30 分

It is said that in 2011, there are about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.

Each applicant will have to provide two grades: the national entrance exam grade G​_E​​ , and the interview grade G_I. The final grade of an applicant is (G_E + G_I)/2. The admission rules are:

Input Specification:

Each input file contains one test case.

Each case starts with a line containing three positive integers: N (≤40,000), the total number of applicants; M (≤100), the total number of graduate schools; and K (≤5), the number of choices an applicant may have.

In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.

Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant's G_E and G_I, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M−1, and the applicants are numbered from 0 to N−1.

Output Specification:

For each test case you should output the admission results for all the graduate schools. The results of each school must occupy a line, which contains the applicants' numbers that school admits. The numbers must be in increasing order and be separated by a space. There must be no extra space at the end of each line. If no applicant is admitted by a school, you must output an empty line correspondingly.

Sample Input:

11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4

Sample Output:

0 10
3
5 6 7
2 8

1 4

思路

struct student
{
    int ge;
    int gi;
    int choices[maxk]; // 记录学生的志愿。
    int key; // 记录学生的id,因为之后会进行排序,学生的索引便不再是他们的id了。
} Stu[maxn];
bool cmp(student s1, student s2) {
    if((s1.ge + s1.gi) != (s2.ge + s2.gi)) {
        return (s1.ge + s1.gi) > (s2.ge + s2.gi);
    }
    else
        return s1.ge > s2.ge;
}

注意点

// 当学校满员后调用该函数,判断时候可以超额录取。
bool isExceeded(int stuid, int schid) {
    int last_stu_id = schAdm[schid][schQuota[schid]-1]; // 获取学校的学生中最后一名的索引
    if((Stu[last_stu_id].ge == Stu[stuid].ge) && (Stu[last_stu_id].gi ==  Stu[stuid].gi))
        return true;
    else return false;

}

AC代码

#include <iostream>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 40001;
const int maxm = 101;
const int maxk = 5;

struct student
{
    int ge;
    int gi;
    int choices[maxk];
    int key;
} Stu[maxn];

// 排序函数
bool cmp(student s1, student s2) {
    if((s1.ge + s1.gi) != (s2.ge + s2.gi)) {
        return (s1.ge + s1.gi) > (s2.ge + s2.gi);
    }
    else
        return s1.ge > s2.ge;
}

int schQuota[maxm]; // 每个学校接受学生的名额上限
vector<int> schAdm[maxm]; // 记录每个学校录取的学生
// 判断是否可以超限添加(当两者的分数完全一样,学校必须接收,无论名额是否超限)
bool isExceeded(int stuid, int schid) {
    int last_stu_id = schAdm[schid][schQuota[schid]-1];
    if((Stu[last_stu_id].ge == Stu[stuid].ge) && (Stu[last_stu_id].gi ==  Stu[stuid].gi))
        return true;
    else return false;

}

int main() {
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);

    for (int i = 0; i < m; ++i)
    {
        scanf("%d", &schQuota[i]);
    }

    for (int i = 0; i < n; ++i)
    {
        int ge, gi;
        scanf("%d%d", &ge, &gi);
        Stu[i].ge = ge;
        Stu[i].gi = gi;
        Stu[i].key = i;
        for(int j = 0; j < k; j++) {
            int choice;
            scanf("%d", &choice);
            Stu[i].choices[j] = choice;
        }
    }

    sort(Stu, Stu+n, cmp);


    for (int i = 0; i < n; ++i)
    {
        int* choices;
        choices = Stu[i].choices;
        for (int j = 0; j < k; ++j)
        {
            //printf("schAdm[%d]: %d %d\n", choices[j], schAdm[choices[j]].size(), schQuota[choices[j]]);
            if(schAdm[choices[j]].size() < schQuota[choices[j]]) {
                //int stuid = Stu[i].key;
                schAdm[choices[j]].push_back(i); // 记录的是排序后学生所在数组的序号,并不是学生真正的id
                break;
            }
            else {
                if(isExceeded(i, choices[j])) {
                    schAdm[choices[j]].push_back(i);
                    break;
                }

            }
        }
    }

    for (int i = 0; i < m; ++i)
    {
        vector<int> adm = schAdm[i]; // 因为记录的是排序后在数组中的序号,这里获取原来的id
        vector<int> ids;
        for (int j = 0; j < adm.size(); ++j)
        {
            int id = Stu[adm[j]].key;
            ids.push_back(id);
        }
        sort(ids.begin(), ids.end());
        for (int j = 0; j < ids.size(); ++j)
        {
            printf("%d", ids[j]);
            if(j != ids.size()-1) printf(" ");
        }
        printf("\n");
    }
}
上一篇下一篇

猜你喜欢

热点阅读