题目

解题思路

这个题要AC其实不容易,思路不太好理清,又是横向排序,又是纵向排序,我最开始做这个题有点凌乱,所以来整理一下思路:

  • 首先一个结构体存储学生信息是少不了的,那这个结构体包含什么呢?id肯定是少不了的,这里要考虑用string还是int,如果用int,那么意味着你要开辟一个比较大的数组。用string的好处在于可以有很多成员函数使用,这里我用的是int。
  • 成绩也是少不了的,那么我们用grade数组来存取ACME,一定是这个顺序,因为题目有一个权重的点需要考虑,我们按权重顺序存,到时候排名次就按for的循环变量累加即可,如果不按这个顺序存,后期不好给学生成绩做一个排名,循环里面的代码不好写。
  • 然后就是排名信息了,每个学生的ACME在总体中的排名,这个是最不好处理的,因为题目要求输出当前学生的最好排名,也就是说你得把每个学生的4门课的排名算出来,那有两种选择,一种是你在结构体中加入rank[4],一种是单独创建一个数组rank[1000000][4]。我选择的后者,横坐标就是id,纵坐标就是4门科目的排名,之所以选用后者是因为方便,然后不需要每一个都遍历,只需要按照下标来找对应的排名即可。

思路理清了,做这个题还有两个需要注意的点:

  • 该排名必须是11345,不能是11234,其实这种很多题都是这样,解决办法也很固定,就是用for循环的循环变量来处理。
  • 所有需要考虑权重的排序,我们的思路都是一样的,即无论是rank数组,还是grade数组,还是v数组,数组按顺序均表示ACME同一个含义,这样可以很好的处理在出现成绩相同需要考虑权重这一问题。
这个题的平均数不用四舍五入也是对的,但是还是养成一个好习惯,所以我用了round函数做处理

实现代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cmath>
#include<sstream>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;

struct Student
{
    int id;
    int grade[4];
}Stu[2001];

char v[]={"ACME"};
int Rank[10000000][4];
int now;

//降序排列,分数高的在前面
bool cmp(Student a,Student b)
{
    return a.grade[now]>b.grade[now];
}

int main()
{
#ifdef ONLINE_JUDGE                
#else    
    freopen("1.txt", "r", stdin);
#endif 

    int n,m;

    cin>>n>>m;

    for(int i=0;i<n;i++)
    {
        cin>>Stu[i].id>>Stu[i].grade[1]>>Stu[i].grade[2]>>Stu[i].grade[3];
        Stu[i].grade[0]=round((Stu[i].grade[1]+Stu[i].grade[2]+Stu[i].grade[3])/3);
    }

    for(now=0;now<4;now++)
    {
        sort(Stu,Stu+n,cmp);
        Rank[Stu[0].id][now]=1;
        for(int j=1 ; j<n ; ++j)
        {
            if(Stu[j].grade[now] == Stu[j-1].grade[now])
                Rank[Stu[j].id][now]=Rank[Stu[j-1].id][now];
            else
                Rank[Stu[j].id][now]=j+1;
        }
    }

    int temp;
    for(int i=0;i<m;i++)
    {
        cin>>temp;

        if(Rank[temp][0]==0)
        {
            cout<<"N/A"<<endl;
        }
        else
        {
            int x=0;
            for(int j=0;j<4;j++)
            {
                if(Rank[temp][j]<Rank[temp][x])
                {
                    x=j;
                }
            }
            cout<<Rank[temp][x]<<" "<<v[x]<<endl;
        }

    }
    return 0;
}

lionの金库