PAT A 1080 Graduate Admission (30分)

本文详细解析了PAT A级1080题的解决方案,通过结构体排序和录取逻辑处理,实现了学生根据成绩降序录取,并正确处理了排名相等的情况。文章分享了从初版代码到最终解决的调试过程,包括输出格式调整和学生录取状态的维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pat A级1080题解

题目

题目大意:
第一行输入学生人数N、学校数M、学生可报考数K。
第二行输入M个学校的招收人数。
接下来N行输入学生的笔试成绩GE、面试成绩GI,K个报考院校。
题目要求先按学生总成绩(GE+GI)/2对学生降序排序,如果总成绩相等则按照GE降序排序,如果两者相同则排名相同,学校的录取方式有两种:
1、学校未招收满,则在排序好的未录取学生中按降序录取
2、学校招收满了,则判断学生的排名是否与最后招收学生排名相等,如果排名相等额外录取。

输出:
输出每一个学校的招收情况,若一个学生也没有则输出空行。

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``

output:
0 10
3
5 6 7
2 8

1 4

题解

一个结构体排序的基础题,cmp函数:


```cpp
int cmp(student a,student b){
if(a.sum!=b.sum)return a.sum>b.sum;
else return a.ge>b.ge;
}

第一次写时1、2用例点过不去,提示格式错误,想到了我输出空格是:


```cpp
for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(sch[i].stulist[j]){
                       // printf("i:%d j:%d stulist:%d",i,j,sch[i].stulist[j]);
                       printf("%d",j);
                    if(!j)printf(" ");
                    }
                }
                printf("\n");
        }

这里的空格输出考虑欠缺,因为空格的输出是和学校录取学生数相等的,因此我在学校结构体里增加了录取学生数:

struct school{
int stuCount;
int blankCount=-1;
int lastRank=-1;
bool stulist[40001]={false};
}sch[101];

然后在按照blankCount的数量来输出空格:

for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(sch[i].stulist[j]){
                       // printf("i:%d j:%d stulist:%d",i,j,sch[i].stulist[j]);
                       printf("%d",j);
                    if(sch[i].blankCount--)printf(" ");
                    }
                }
                printf("\n");
        }

最后献上代码和思路:

#include<bits/stdc++.h>
#include<math.h>
using namespace std;
struct student{
int id;
int ge,gi;
double sum;
int aim[6];//目标院校
int rank;
bool isAdmitted=false;//录取状态
}stu[40001];

struct school{
int stuCount;
int blankCount=-1;
int lastRank=-1;
bool stulist[40001]={false};
}sch[101];

int cmp(student a,student b){
if(a.sum!=b.sum)return a.sum>b.sum;
else return a.ge>b.ge;
}
int main()
{
    int n,m,k;
    cin>>n>>m>>k;
    for(int i=0;i<m;i++)
        cin>>sch[i].stuCount;

        for(int i=0;i<n;i++){
            cin>>stu[i].ge>>stu[i].gi;
            stu[i].sum=(stu[i].ge+stu[i].gi)/2.0;
            stu[i].id=i;
            for(int j=0;j<k;j++)cin>>stu[i].aim[j];
        }

        sort(stu,stu+n,cmp);

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

        for(int i=0;i<n;i++){
            for(int j=0;j<k;j++){
                if(!stu[i].isAdmitted && (sch[stu[i].aim[j]].stuCount>0  || stu[i].rank==sch[stu[i].aim[j]].lastRank)){//该学生没被录取并且学校未录满或该学生排名和学校最后一名相等时进行录取
                    sch[stu[i].aim[j]].stuCount--;
                    sch[stu[i].aim[j]].blankCount++;//录取学生数+1
                    sch[stu[i].aim[j]].lastRank=stu[i].rank;//此时学生已经排完序,保证最后排名为最低
                    sch[stu[i].aim[j]].stulist[stu[i].id]=true;//将该学生存入学校里
                    stu[i].isAdmitted=true;//表示该学生已被录取
                }
            }
        }

        int acount;
        for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(sch[i].stulist[j]){
                       printf("%d",j);
                    if(sch[i].blankCount--)printf(" ");//blankCount控制空格数量
                    }
                }
                printf("\n");
        }


        /* 这组测试数据应该输出5空行
5 5 3
0 0 0 5 5
100 100 0 1 2
100 99 1 2 0
99 100 2 1 0
99 99 1 0 2
98 98 2 0 1
        */
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值