PAT(甲级)1012 The Best Rank (25point(s))

题目

题目链接

思路

题目大意:给n个学生的各科成绩,对每一科都进行排名,取排名最好的一科作为该名同学的最终排名;
最好把每名同学每科的排名用一个数组Rank[id][4]都预先记录下来,然后在根据下标去查询最好的排名,这样做时间复杂度是最低的,只有排序的nlogn;
如何把每名同学各科成绩的排名统计出来?依次以平均成绩,c, m, e作为排序标准将stu数组排序,共循环4次,然后从前往后遍历stu数组,把每名同学这科成绩对应的排名填到Rank数组的对应位置。注意,每名同学的id可以作为Rank数组的下标;
然后依次去查询m个同学就可以了,查询时要先判断这名同学存在不存在,再输出排名最好的排名及科目;

代码
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 10;

struct node{
     int id;//存储6位数字的id
     int grade[4];//依次存储平均分,c, m, e
}stu[2010];

int Rank[maxn][4] = {0};//存储每个人的id和每门课对应的排名
char sub[4] = {'A', 'C', 'M', 'E'};
int n, m, idx;

bool cmp(node a, node b){
     return a.grade[idx] > b.grade[idx];
}

int main()
{
     fill(Rank[0], Rank[0] + maxn * 4, 0);
     scanf("%d%d", &n, &m);
     //读入成绩
     for(int i = 0; i < n; i ++){
          scanf("%d%d%d%d", &stu[i].id, &stu[i].grade[1], &stu[i].grade[2], &stu[i].grade[3]);
          stu[i].grade[0] = stu[i].grade[1] + stu[i].grade[2] + stu[i].grade[3];
     }
     //处理排名,一共循环4次,先计算平均分,在分别计算c, m, e
     for(int i = 0; i < 4; i ++){
          idx = i;
          sort(stu, stu + n, cmp);
          int r = 1, last = stu[0].grade[i];
          //依次赋值排名
          for(int j = 0; j < n; j ++){
               //排序后,如果当前分数与之前分数一致,排名不变
               if(stu[j].grade[i] == last) Rank[stu[j].id][i] = r;
               //如果分数不一致,排名变为下标加一
               else{
                    Rank[stu[j].id][i] = j + 1;
                    last = stu[j].grade[i];
                    r = j + 1;
               }
          }
     }
     //查询排名
     int id;
     for(int i = 0; i < m; i ++){
          scanf("%d", &id);
          //如果id不存在
          if(Rank[id][0] == 0){
               printf("N/A\n");
               continue;
          }
          int bestRank = Rank[id][0], bestSub = 0;
          for(int j = 1; j < 4; j ++){
               if(Rank[id][j] < bestRank){
                    bestRank = Rank[id][j];
                    bestSub = j;
               }
          }
          printf("%d %c\n", bestRank, sub[bestSub]);
     }
     system("pause");
     return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值