1080 Graduate Admission (30分)

1 篇文章 0 订阅
1 篇文章 0 订阅

1080 Graduate Admission (30分)

在这里插入图片描述
在这里插入图片描述

思路

思路的话 我的方向是学生挑学校
学生成绩排好序之后 优秀的学生先挑学校 到后面的学生的时候 有的学校已经录满了 那就换第二志愿、第三志愿、依次下去 直到录取结束

第一次的代码(只拿了24分 不知道哪错了)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
struct student
{
    int id;  //序号
    int bishi;//笔试成绩
    int mianshi;//面试成绩
    int choice[10];//喜欢的学校
    int score;//最终分数
    int rank;//排名
    int admitted;//录取的学校
    int lastone ;
}stu[40100];
bool cmp(student a, student b)
{
    if (a.score == b.score) return a.bishi > b.bishi;
    else return a.score > b.score;

}
int n, m, k;
bool Rank(student a, int x)
{
    student b;
    for (int i = 0;i < n;i++)  //找到喜欢学校已招的最后一名
    {
        if (stu[i].admitted == a.choice[x] && stu[i].lastone == 1)
        {
            b = stu[i];
        }
    }
    if (a.rank == b.rank) //如果和喜欢学校已招的最后一名排名一样的话 那就录取
    {
        return true;
    }
    else
    {
        return false;
    }

}
int main()
{
    int school[1100] = { 0 };//每个学校已经招的人
    int quota[1100];    //每个学校的名额
    cin >> n >> m >> k;
    for (int i = 0;i < m;i++)
    {
        cin >> quota[i];
        //每个学校的名额
    }
    for (int i = 0;i < n;i++)
    {
        stu[i].id = i;
        memset(stu[i].choice,-1,sizeof(stu[i].choice));
        stu[i].admitted=-1;
        stu[i].lastone=0;
        cin >> stu[i].bishi >> stu[i].mianshi;
        stu[i].score = stu[i].bishi + stu[i].mianshi;
        for (int j = 0;j < k;j++)
        {
            cin >> stu[i].choice[j];
        }
    }
    sort(stu, stu + n, cmp);
    //排名
    stu[0].rank = 1;
    for (int i = 1;i < n;i++)
    {
        if (stu[i].score == stu[i - 1].score && stu[i].bishi == stu[i - 1].bishi)
        {
            stu[i].rank = stu[i - 1].rank;
        }
        else
        {
            stu[i].rank = i + 1;
        }
    }
    //排好序 学生开始挑学校
    for (int i = 0;i < n;i++)
    {
        int j;
        for (j = 0;j < k;j++)
        {
            if (school[stu[i].choice[j]] < quota[stu[i].choice[j]])//如果喜欢的学校没满 就直接进去
            {
                if (school[stu[i].choice[j]] == quota[stu[i].choice[j]] - 1)
                {
                    stu[i].lastone = 1;
                }
                school[stu[i].choice[j]]++;  //学校已招人数+1
                stu[i].admitted = stu[i].choice[j];//学生录取学校确定
                break;
            }
            else if (school[stu[i].choice[j]] == quota[stu[i].choice[j]] && Rank(stu[i], stu[i].choice[j]) == true)//如果学校已经招满了 但是和招满学校的最后一名排名一样  扩招
            {
                school[stu[i].choice[j]]++;  //学校已招人数+1
                stu[i].admitted = stu[i].choice[j];//学生录取学校确定
                break;
            }
            else
            {
                continue;
            }
        }
        if (j == k)
        {
            stu[i].admitted = -1; //这个学生没录到
        }
    }
    //录取结束 
    int shuchu[1100][1100];  //为了能够从小到大输出 搞一个二维数组输出

    memset(shuchu, -1, sizeof(shuchu)); // 全部赋值为-1

    for (int i = 0;i < m;i++)
    {
        for (int j = 0;j < n;j++)
        {
            if (stu[j].admitted != -1) //如果不为-1 即被录取了 
            {
                shuchu[stu[j].admitted][stu[j].id] = stu[j].id; //shuchu【录取学校】【id】=id;
            }
        }
    }

    for (int i = 0;i < m;i++)
    {
        int flag = 0;                   //为了方便输出的空格 
        for (int j = 0;j < n;j++)
        {
            if (shuchu[i][j] != -1 && flag == 0)  //第一个只输出第一个数
            {
                cout << shuchu[i][j];
                flag = 1;
            }
            else if (shuchu[i][j] != -1 && flag == 1)  //后面的输出空格+输出的数 
            {
                cout << " " << shuchu[i][j];
            }
        }
        cout << endl;                                     //换行
    }


    return 0;
}

换了方法后的代码(30分)

#include<iostream>
#include<cstring>
#include<cstdio>
#include<string>
#include<algorithm>
using namespace std;
struct student
{
    int id;
    int bishi, mianshi, sum;
    int rank;
    int num;
    int choice[6] = { -1,-1,-1,-1,-1,-1 };
}stu[40010];
struct school
{
    int lastone;
    int quota;
    int num;
    int id[40010];
}s[110];
bool cmp(student a , student b)
{
    if (a.sum == b.sum) return a.bishi > b.bishi;
    else return a.sum > b.sum;
}
int main()
{
    int n, m, k;
    cin >> n >> m >> k;
    for (int i = 0;i < m;i++)
    {
        cin >> s[i].quota;
        s[i].num = 0;
        s[i].lastone = -1;
        memset(s[i].id, -1, sizeof(s[i].id));
    }
    for (int i = 0;i < n;i++)
    {
        stu[i].id = i;
        cin >> stu[i].bishi >> stu[i].mianshi;
        stu[i].sum = stu[i].bishi + stu[i].mianshi;
        for (int j = 0;j < k;j++)
        {
            cin >> stu[i].choice[j];

        }
    }
    sort(stu, stu + n, cmp);
    for (int i = 0;i < n;i++)
    {
        stu[i].num = i;      //num对应的是排序完之后的顺序 此处是为了方便找到录取学校的最后一名
    }
    stu[0].rank = 1;
    for (int i = 1;i < n;i++)
    {
        if (stu[i].sum == stu[i - 1].sum && stu[i].bishi == stu[i - 1].bishi)
        {
            stu[i].rank = stu[i - 1].rank;
        }
        else
        {
            stu[i].rank = i + 1;
        }
    }
    //开始录取
    for (int i = 0;i < n;i++)
    {
        for (int j = 0;j < k;j++)
        {
            if (s[stu[i].choice[j]].num < s[stu[i].choice[j]].quota) //没招满
            {
                if (s[stu[i].choice[j]].num == s[stu[i].choice[j]].quota - 1) //如果是最后一个录取的
                {
                    s[stu[i].choice[j]].lastone = stu[i].num;   //一定要是num  因为接下来是stu[s[stu[i].choice[j]].lastone].rank 这里需要的是排序后的序列 而不是ID
                }
                s[stu[i].choice[j]].id[stu[i].id] = stu[i].id;
                s[stu[i].choice[j]].num++;
                break;
            }

            else if (stu[i].rank == stu[s[stu[i].choice[j]].lastone].rank && s[stu[i].choice[j]].num >= s[stu[i].choice[j]].quota)
            {
                s[stu[i].choice[j]].id[stu[i].id] = stu[i].id;
                s[stu[i].choice[j]].num++;
                break;
            }
            else
            {
                continue;
            }
        }
    }

    for (int i = 0;i < m;i++)
    {
        int flag = 0;
        if (s[i].num > 0)
        {
            for (int j = 0;j < n;j++)
            {
                if (s[i].id[j] != -1 && flag==0)
                {
                    cout << s[i].id[j];
                    flag = 1;
                }
                else if(s[i].id[j] != -1 && flag == 1)
                {
                    cout << " " << s[i].id[j];
                }
            }
            
        }
        cout << endl;
    }

    return 0;
}
第一次的代码里面 我用了一个结构体数组 然后创建了许多的数组来表示学校的
那一面
然后就发现只能拿24分 运行超时了一个点 可能是在找最后一名学生那里用的循环
太多 所以这种方法有点费时间
于是 第二次我用了两个结构体数组 学生的为一组 学校的为一组 然后就AC啦!

如果有哪位大佬能帮我找一下第一个代码的错误 麻烦告诉我一下 有偿!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值