题目链接

1012 The Best Rank (25 分)

思路

结构题排序,但是这题不好拿满分,有个细节巨坑:相同分数的赋给的排名要相同,举个例子,88,88,99,70,排名为2,2,1,4。

AC代码

#include <bits/stdc++.h>
using namespace std;
const int N=2010,inf=0x3f3f3f3f;
struct node
{
    int id,pos;
    double a,c,m,e;
}p[N],t[N];
struct node1
{
    int rk[4];
}ans[N]; 
// ans[i].rk[0]表示第i个同学分数A的排名
// ans[i].rk[1]表示第i个同学分数C的排名
// ans[i].rk[2]表示第i个同学分数M的排名
// ans[i].rk[3]表示第i个同学分数E的排名
unordered_map<int,pair<int,char> >vis;
bool cmp_a(node s1,node s2){return s1.a>s2.a;}
bool cmp_c(node s1,node s2){return s1.c>s2.c;}
bool cmp_m(node s1,node s2){return s1.m>s2.m;}
bool cmp_e(node s1,node s2){return s1.e>s2.e;}
int main()
{
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>p[i].id>>p[i].c>>p[i].m>>p[i].e;
        p[i].a=(p[i].c+p[i].m+p[i].e)/3.0;
        p[i].pos=i; // pos为原序号
        t[i]=p[i]; // t[i]是p[i]的拷贝
    }
    // 1.排序a
    sort(p+1,p+n+1,cmp_a);
    int last=1;
    for(int i=1;i<=n;i++)
    {
        if(i>1&&p[i-1].a==p[i].a)ans[p[i].pos].rk[0]=last; // 与分数相同的最前面一位排名并列
        else ans[p[i].pos].rk[0]=i,last=i;
    }
    for(int i=1;i<=n;i++) // 还原p数组,以便下次重新排序
        p[i]=t[i];
    // 2.排序c
    sort(p+1,p+n+1,cmp_c);
    last=1;
    for(int i=1;i<=n;i++)
    {
        if(i>1&&p[i-1].c==p[i].c)ans[p[i].pos].rk[1]=last; // 与分数相同的最前面一位排名并列
        else ans[p[i].pos].rk[1]=i,last=i;
    }
    for(int i=1;i<=n;i++)
        p[i]=t[i];
    // 3.排序m
    sort(p+1,p+n+1,cmp_m);
    last=1;
    for(int i=1;i<=n;i++)
    {
        if(i>1&&p[i-1].m==p[i].m)ans[p[i].pos].rk[2]=last; // 与分数相同的最前面一位排名并列
        else ans[p[i].pos].rk[2]=i,last=i;
    }
    for(int i=1;i<=n;i++)
        p[i]=t[i];
    // 4.排序e
    sort(p+1,p+n+1,cmp_e);
    last=1;
    for(int i=1;i<=n;i++)
    {
        if(i>1&&p[i-1].e==p[i].e)ans[p[i].pos].rk[3]=last; // 与分数相同的最前面一位排名并列
        else ans[p[i].pos].rk[3]=i,last=i;
    }
    for(int i=1;i<=n;i++)
        p[i]=t[i];
    char mp[4]={'A','C','M','E'};
    char c;
    for(int i=1;i<=n;i++)
    {
        int mi=inf;
        for(int j=0;j<4;j++)
        {
            if(ans[i].rk[j]<mi)
            {
                mi=ans[i].rk[j];
                c=mp[j];
            }
        }
        vis[p[i].id]=make_pair(mi,c); // 存答案
    }
    int id;
    while(m--)
    {
        cin>>id;
        pair<int,char> t1=vis[id];
        if(t1.first!=0&&t1.second!=0)printf("%d %c\n",t1.first,t1.second);
        else printf("N/A\n");
    }
    return 0;
}
/*
4 4
1 88 88 88
2 88 88 88
3 99 99 99
4 70 70 70
1
2
3
4
*/

其他思路

结构体排序有点复杂了,其实可以桶排序,记录[0,100]区间内每个分数的人数(计算平均分可四舍五入取整),从而计算排名。

参考 https://blog.csdn.net/weixin_43869268/article/details/88352606