• 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);
    
  • 相关阅读:
    银联支付集成之 ---- 安卓
    在Mac系统下配置PHP运行环境
    ios工程中一天只让显示一次的广告,或是弹出窗,如何实现
    iOS工程中一天只让进行一次的操作如何做?
    简单实现UIlabel可复制功能
    iOS添加测试设备与调试
    iOS-最全的App上架教程
    javaIO--文件操作类
    javaIO--字符流
    javaIO--字节流
  • 原文地址:https://www.cnblogs.com/fxh0707/p/14248124.html
Copyright © 2020-2023  润新知