• PAT 甲级 1012 The Best Rank (25 分)(结构体排序)


    题意:

    为了评估我们第一年的CS专业学生的表现,我们只考虑他们的三个课程的成绩:C - C编程语言,M - 数学(微积分或线性代数)和E - 英语。同时,我们鼓励学生强调自己的最优秀队伍 - 也就是说,
    在三个课程和平均成绩的四个职级中,我们打印每个学生的最佳排名。

    例如,C,M,E和A - 4名学生的成绩如下:

    StudentID C M E A
    310101 98 85 88 90
    310102 70 95 88 84
    310103 82 87 94 88
    310104 91 91 91 91
    那么所有学生的最佳排名都是第一,因为第一名在C编程语言方面做得最好,而第二名则是数学第二名,英文第三名,平均第三名。

    输入

    每个输入文件包含一个测试用例。每个案例以包含2个数字N和M(<= 2000)的行开始,
    分别是学生人数和学生人数。然后按N行,每个包含一个6位数字的学生ID,其后是C,M和E顺序的该学生的三个整数等级(在[0,100]范围内)。然后在那里是M行,每行包含学生ID

    输出

    对于每个M学生,以一行打印他/她的最佳排名,以及由空格分隔的相应排名的符号。

    排名方法的优先级排序为A> C> M> E。因此,如果学生获得相同最佳排名有两种或更多种方式,则输出优先级最高的排名。
    如果学生不在评分清单上,只需输出“N / A”即可。

    思路:

    1.我把ID设置成了String,实际上本来用int也是可以的。这就对判断M个字符串中是否之前又出现过造成了麻烦。对此,我一开始设置的node2结构体里,先给每个排名rank赋值为99999,顺便把字符串放队列里,然后再排序,再遍历队列,如果新来的字符串之前没有出现过,那么它的rank还将是99999,就输出N/A

    2.排序弄得我头大,113336,而不是112223,也不是123456。首先本来sort里比较器>=就可以了,偏偏段错误。原因:https://blog.csdn.net/aichirourou_66/article/details/80928249

    只好自己弄排序的名次,由此引入了k来存储上一个的名次。j=k,而不是M[a[i-1].s].rank,这个地方粗心损失了不少时间。

    3.排序我居然重复写了四遍,实际上放在一个循环里就可以了。。。

    AC代码:

    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    struct node{//存放学生信息 
        string s;
        int c;
        int ma;
        int e;
        double av;
    }a[5005];
    struct node2//存放rank信息 
    {
        int rank;//排名 
        char course;//课程 
        node2(int _rank=99999,char _course='A')
        {
            rank=_rank;
            course=_course;
        }
    };
    map<string,node2>M;//将ID与rank信息一一对应 
    queue<string>Q; //用于放后面输入的M个字符串 
    
    bool cmp_av(const node &x, const node &y) {
        return x.av > y.av;//不能>=,会段错误 
    }
    bool cmp_c(const node &x, const node &y) {
        return x.c > y.c;
    }
    bool cmp_ma(const node &x, const node &y) {
        return x.ma > y.ma;
    }
    bool cmp_e(const node &x, const node &y) {
        return x.e > y.e;
    }
    string ss;
    int main()
    {
        cin>>n>>m;
        while(!Q.empty()) Q.pop();
        for(int i=1;i<=n;i++){
            cin>>a[i].s>>a[i].c>>a[i].ma>>a[i].e;
            a[i].av=int((a[i].c+a[i].ma+a[i].e)*1.0/3+0.5);
            M[a[i].s]=node2(99999,'A');//先给个默认的rank信息 
        }
        
        for(int i=1;i<=m;i++)
        {
            cin>>ss;
            Q.push(ss);//先放进去,之后还要再遍历 
            M[a[i].s]=node2(99999,'A');//先给个默认的rank信息 
        }
        sort(a+1,a+1+n,cmp_av);
        int k=1;//为了名次设置的,113336,而不是112223,也不是123456 
        for(int i=1;i<=n;i++)
        {
            int j=i;
            if(i>1 && a[i].av==a[i-1].av){
                j=k;//为前面的名词 
            }
            else{
                k=j;//名词为j,同时更新k 
            }
            if(M[a[i].s].rank>j){
                M[a[i].s].rank=j;
                M[a[i].s].course='A';
            }
    //        cout<<j<<" "<<a[i].s<<" "<<a[i].av<<endl;
        }
    
        sort(a+1,a+1+n,cmp_c);
    //    cout<<endl;
        k=1;
        for(int i=1;i<=n;i++)
        {
            int j=i;
            if(i>1 && a[i].c==a[i-1].c){
                j=k;
            }
            else{
                k=j;
            }
            if(M[a[i].s].rank>j){
                M[a[i].s].rank=j;
                M[a[i].s].course='C';
            }
    //        cout<<j<<" "<<a[i].s<<" "<<a[i].c<<endl;
        }
        
        sort(a+1,a+1+n,cmp_ma);
    //    cout<<endl;
        k=1;
        for(int i=1;i<=n;i++)
        {
            int j=i;
            if(i>1 && a[i].ma==a[i-1].ma){
                j=k;
            }
            else{
                k=j;
            }
            if(M[a[i].s].rank>j){
                M[a[i].s].rank=j;
                M[a[i].s].course='M';
            }
    //        cout<<j<<" "<<a[i].s<<" "<<a[i].ma<<endl;
        }
        
        sort(a+1,a+1+n,cmp_e);
    //    cout<<endl;
        k=1;
        for(int i=1;i<=n;i++)
        {
            int j=i;
            if(i>1 && a[i].e==a[i-1].e){
                j=k;
            }
            else{
                k=j;
            }
            if(M[a[i].s].rank>j){
                M[a[i].s].rank=j;
                M[a[i].s].course='E';
            }
    //        cout<<j<<" "<<a[i].s<<" "<<a[i].e<<endl;
        }
        while(!Q.empty())
        {
            ss = Q.front();
            Q.pop();
            //cout<<ss<<" "<<M[ss].rank<<endl;
            if(M[ss].rank==99999){//不存在的情况 
                cout<<"N/A"<<endl;
            }
            else{
                cout<<M[ss].rank<<" "<<M[ss].course<<endl;
            }
        }
        return 0;
     } 
  • 相关阅读:
    电脑开机时一直滴滴的响开不了机是为什么?
    电脑开机时一直滴滴的响开不了机是为什么?
    winform窗体应用实现淡入淡出等效果
    winform窗体应用实现淡入淡出等效果
    windows-如何生成转储(dmp)文件--工具篇
    面向对象(三)- Java类的方法
    面向对象 (二)- Java类的属性
    面向对象 (二)- Java类的属性
    面向对象 (一)- Java中的类和对象
    面向对象 (一)- Java中的类和对象
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/13270696.html
Copyright © 2020-2023  润新知