PAT甲 - 1012 The Best Rank

题目:

为了评估我们第一年 CS 专业学生的表现,我们只考虑他们三门课程的成绩:C - C 编程语言、M - 数学(微积分或线性代数)和 E - 英语。同时,我们鼓励学生强调他们最好的排名——即在三个课程和平均成绩的四个排名中,我们为每个学生打印最好的排名。
例如,C、M、E 和 A 的成绩 - 4 名学生的平均成绩如下:
学生证 C M E A
310101 98 85 88 90
310102 70 95 88 84
310103 82 87 94 88
310104 91 91 91 91

然后所有学生的最好成绩是第一名,因为第一名在C程序设计语言方面做得最好,而数学第二名,英语第三名,平均排名最后一名。

输入规格:
每个输入文件包含一个测试用例。每个案例以一行包含 2 个数字 N 和 M(≤2000)开始,分别是学生总数和检查排名的学生人数。然后是N行,每行包含一个6位数的学生ID,后面是该学生的三个整数等级([0, 100]范围内),依次为C、M、E。然后有是 M 行,每行包含一个学生 ID。

输出规格:
对于 M 名学生中的每一个,将他/她的最佳排名和相应排名的符号打印在一行中,并用空格分隔。
排序方法的优先级顺序为 A > C > M > E。因此,如果学生有两种或多种方式获得相同的最佳排名,则输出优先级最高的一种。
如果学生不在评分列表中,只需输出 N/A。

样本输入:
5 6
310101 98 85 88
310102 70 95 88
310103 82 87 94
310104 91 91 91
310105 85 90 90
310101
310102
310103
310104
310105
999999

示例输出:

1 C
1 M
1 E
1 A
3 A
N/A

题目大意:

给出n个学生的三门分数,平均分得自己求,然后根据四个分数总体比较降序排序,这样每个学生的自己的四个分数都会有排名,找到排名最优的输出,名次相同则按A>C>M>E顺序输出,ID不存在则输出N/A

解题思路:

在结构体里定义两个大小为4的数组,score数组储存学生的四个成绩,另一个储存学生的四个成绩的排名,在输入时同时得出平均分。

而后利用sort对A、C、M、E的成绩分别进行降序排序,每次排序记录每个学生在该成绩的排名是多少,最后进行ID验证输出即可。

注:当出现成绩相同时排名应该也相同,不然会导致有个测试点过不去  如:1 2 3 4 5,如果成绩1与成绩2相同,排名则为1 1 3 4 5。

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int flag;
struct student{
    int best;
    int id;
    int score[4];
    int rank[4];
};

bool cmp(student a,student b){
    //按单个科目分数进行降序排序
    return a.score[flag]>b.score[flag];
}

int main()
{
    int n,m;
    const char z[4]={'A','C','M','E'};
    scanf("%d %d",&n,&m);
    student stu[2005];
    for(int i=0;i<n;i++){
        cin>>stu[i].id>>stu[i].score[1]>>stu[i].score[2]>>stu[i].score[3];
        //计算平均数
        stu[i].score[0]=(stu[i].score[1]+stu[i].score[2]+stu[i].score[3])/3;
        stu[i].best=0;
    }
    for(flag=0;flag<4;flag++){
        sort(stu,stu+n,cmp);
        for(int j=0;j<n;j++){
            //判断如果该学生该成绩与上一名次的学生该成绩一样,则名次也应一样
            if(j>=1&&stu[j].score[flag]==stu[j-1].score[flag])stu[j].rank[flag]=stu[j-1].rank[flag];
            否则就记录正常名次
            else stu[j].rank[flag]=j;
            判断学生名次最佳的是哪门课目 记录最佳科目的下标
            if(stu[j].rank[flag]<stu[j].rank[stu[j].best])stu[j].best=flag;
        }
    }
    for(int i=0;i<m;i++){
        int num;
        cin>>num;
        for(int j=0;j<n;j++){
            if(stu[j].id==num){
                //因为记录名次是从0开始记录,所以输出应该+1
                printf("%d %c\n",stu[j].rank[stu[j].best]+1,z[stu[j].best]);
                break;
            }
            if(j==n-1){
                printf("N/A\n");
            }
        }
    }
    return 0;
}

对于最后ID验证也可以在开始的时候记录好ID是否存在并进行相关操作,有些地方可以更好更简洁一些,大体思路差不多吧

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值