zoukankan      html  css  js  c++  java
  • 1012 The Best Rank (25分)

    题意
    现已知n个考生的3门课分数C、M、E,而平均分数A可以由这3个分数得到。现在分别按这4个分数对n个考生从高到低排序,这样对每个考生来说,就会有4个排名且每个分数都会有一个排名。接下来会有m个查询,每个查询输入一个考生的ID,输出该考生4个排名中最高的那个排名及对应是A、C、M、E中的哪一个。如果对不同课程有相同排名的情况,则按优先级A>C>M>E输出;如果查询的考生ID不存在,则输出N/A。

    毒瘤题。。。之后找机会重写下吧。。。毕竟现在的码风惨不忍睹,而且(color{green}{AcWing})上只过了(3)个点=_=

    注意分数相同的同学名次相同,并且小于当前分数的同学的名次依次向后递进。

    例如:1、1、3、4、5,而不是1、1、2、3、4。

    const int N=2010;
    struct Stu {
        int c_rank,m_rank,e_rank,avg_rank;
    }a[N];
    PII c[N],m[N],e[N];
    unordered_map<string,int> mp;
    PDI avg[N];
    int n,q;
    
    
    int main()
    {
        cin>>n>>q;
    
        for(int i=0;i<n;i++)
        {
            string id;
            cin>>id>>c[i].fi>>m[i].fi>>e[i].fi;
            avg[i].fi=(c[i].fi+m[i].fi+e[i].fi)/3.0;
            mp[id]=i;
            c[i].se=m[i].se=e[i].se=avg[i].se=i;
        }
    
        sort(c,c+n,greater<PII>());
        sort(m,m+n,greater<PII>());
        sort(e,e+n,greater<PII>());
        sort(avg,avg+n,greater<PDI>());
    
        int tot=1;
        for(int i=0;i<n;i++)
        {
            if(i && c[i].fi == c[i-1].fi)
                a[c[i].se].c_rank=a[c[i-1].se].c_rank;
            else
                a[c[i].se].c_rank=tot;
            tot++;
        }
        tot=1;
        for(int i=0;i<n;i++)
        {
            if(i && m[i].fi == m[i-1].fi)
                a[m[i].se].m_rank=a[m[i-1].se].m_rank;
            else
                a[m[i].se].m_rank=tot;
            tot++;
        }
        tot=1;
        for(int i=0;i<n;i++)
        {
            if(i && e[i].fi == e[i-1].fi)
                a[e[i].se].e_rank=a[e[i-1].se].e_rank;
            else
                a[e[i].se].e_rank=tot;
            tot++;
        }
        tot=1;
        for(int i=0;i<n;i++)
        {
            if(i && avg[i].fi == avg[i-1].fi)
                a[avg[i].se].avg_rank=a[avg[i-1].se].avg_rank;
            else
                a[avg[i].se].avg_rank=tot;
            tot++;
        }
    
        while(q--)
        {
            string id;
            cin>>id;
            if(!mp.count(id))
            {
                puts("N/A");
                continue;
            }
            int x=mp[id];
    
            int rank=min(min(a[x].c_rank,a[x].m_rank),min(a[x].e_rank,a[x].avg_rank));
    
            if(a[x].avg_rank == rank)
                cout<<rank<<' '<<'A'<<endl;
            else if(a[x].c_rank == rank)
                cout<<rank<<' '<<'C'<<endl;
            else if(a[x].m_rank == rank)
                cout<<rank<<' '<<'M'<<endl;
            else
                cout<<rank<<' '<<'E'<<endl;
        }
    
    
        //system("pause");
        return 0;
    }
    

    (update on 2021.2.14)
    情人节快乐!

    思路

    1. 考虑到优先级为A>C>M>E,不妨在设置数组时就按这个顺序分配序号为0 ~ 3的元素,即0对应A、1对应C、2对应M及3对应E。
    2. 按顺序枚举A、C、M、E,对每个分数,将所有考生排序,并在Rank数组中记录排名。
    3. 在查询时,对读入的查询ID,先看其是否存在。如果存在,选出Rank[pos][0] ~ Rank[pos][3]中数字最小(即排名最高)的那个即可。

    由于排序会改变(a)数组,因此在读入时需要记录下标位置(pos),再存储至Rank数组中对应(pos)的位置。

    注意点

    1. 要注意优先级顺序是A>C>M>E,所以为了方便枚举,在设置数组时尽量把A放在C、M、E前面。
    2. 排名时,相同分数算作排名相同,所以91、90、 88、 88、84的排名应该算作1、2、3、3、5。在具体实现时,切记不要算作1、2、3、3、4。
    3. 本题没有明示平均分是否需要取整以及取整方式,根据题目描述中的例子可以看出是四舍五入。但本题采用向下取整的方式也能通过,或者采用更简洁的方式——不取平均,直接存储三门课的总分。
    struct Stu {
        string id;
        int grade[4];
        int pos;
    }a[N];
    int Rank[N][4];
    unordered_map<string,Stu> mp;
    char course[]={'A','C','M','E'};
    int n,m;
    int idx;
    
    bool cmp(Stu &a, Stu &b)
    {
        return a.grade[idx] > b.grade[idx];
    }
    
    int main()
    {
        cin>>n>>m;
    
        for(int i=0;i<n;i++)
        {
            cin>>a[i].id>>a[i].grade[1]>>a[i].grade[2]>>a[i].grade[3];
            a[i].pos=i;
    
            for(int j=1;j<4;j++) a[i].grade[0]+=a[i].grade[j];
    
            mp[a[i].id]=a[i];
        }
    
        for(idx=0;idx<4;idx++)
        {
            sort(a,a+n,cmp);
    
            for(int i=0;i<n;i++)
            {
                if(i && a[i].grade[idx] == a[i-1].grade[idx])
                    Rank[a[i].pos][idx]=Rank[a[i-1].pos][idx];
                else
                    Rank[a[i].pos][idx]=i+1;
            }
        }
    
        while(m--)
        {
            string id;
            cin>>id;
            if(!mp.count(id)) puts("N/A");
            else
            {
                int pos=mp[id].pos;
                int minidx=0;
                for(int i=1;i<4;i++)
                    if(Rank[pos][i] < Rank[pos][minidx])
                        minidx=i;
                cout<<Rank[pos][minidx]<<' '<<course[minidx]<<endl;
            }
        }
    
        //system("pause");
        return 0;
    }
    

    至于(color{green}{AcWing})上只能过(3)个点,(color{green}{AcWing})上平均成绩为三科成绩平均值四舍五入取整的结果,所以加上下面一行就可以了。

    a[i].grade[0]=round(a[i].grade[0]/3.0);
    
  • 相关阅读:
    Minimum Depth of Binary Tree leetcode java
    Maximum Depth of Binary Tree leetcode java
    Symmetric Tree leetcode java
    Same Tree leetcode java
    Binary Tree Postorder Traversal leetcode java
    Binary Tree Preorder Traversal leetcode java
    Binary Tree Inorder Traversal leetcode java
    Combinations leetcode java
    一键清除Centos iptables 防火墙所有规则
    阿里云centos7.7x64安装open,并配置ip转发和nat伪装
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14248124.html
Copyright © 2011-2022 走看看