PAT 甲级1025 PAT Ranking (25 分)(结构体排序,第一次超时了,一次sort即可小技巧优化)

题意:

给定一次PAT测试的成绩,要求输出考生的编号,总排名,考场编号以及考场排名。

分析:

  题意很简单嘛,一开始上来就,一组组输入,一组组排序并记录组内排名,然后再来个总排序并算总排名,结果发现最后一个测试点超时。

  发现自己一开始太傻太盲目,其实只要一次性全部输进来,记录好考场编号,一次排序就可以了。既然只排了一次,怎么计算考场排名呢,这里我用了三个数组

int g_rank[100];//记录各个考场当前排到的名次 (当前最后一个人的名次)
int g_score[100];//记录个考场当前排到的最后一个人的分数 
int g_num[100];//记录个考场当前已经排好队的人数  

帮助计算考场排名

        //计算分组排名 
        int p=a[i].num;//他属于第p组 
        if(g_rank[p]==0){//如果他是本小组第一名 
            a[i].rank=1;
            g_rank[p]=1;//当前组排到了第几名 
            g_score[p]=a[i].score;//本小组目前排下来最后一名的分数 
            g_num[p]=1;//当前组排到了第几个人 
        }else{
            g_num[p]++;//更新人数 
            if(g_score[p]==a[i].score) {//如果此人与本组的上一人的分数相同 
                a[i].rank=g_rank[p];//就是本小组上一名的名次             
            }else{//不同的话 
                a[i].rank=g_num[p];//那么他的名次是本组的人数 
                g_rank[p]=g_num[p];//更新当前本组最后一人名次 
                g_score[p]=a[i].score;//更新分数 
            }        
        }

AC代码:

#include<bits/stdc++.h> 
using namespace std;
struct node{
    string name;
    int score;
    int num;
    int rank;
    int frank;
}a[30005];
bool cmp(node x,node y){
    if(x.score==y.score){
        return x.name<y.name;
    }else{
        return x.score>y.score;
    }
}
int g_rank[100];//记录各个考场当前排到的名次 (当前最后一个人的名次)
int g_score[100];//记录个考场当前排到的最后一个人的分数 
int g_num[100];//记录个考场当前已经排好队的人数  
int main(){
    int n,k;
    cin>>n;
    int r=1;
    for(int i=1;i<=n;i++){
        cin>>k;
        for(int j=1;j<=k;j++){
            cin>>a[r].name>>a[r].score;
            a[r].num=i;//考场编号 
            r++;
        }
    }
    sort(a+1,a+r,cmp);
    cout<<r-1<<endl;
    memset(g_rank,0,sizeof(g_rank));
    for(int i=1;i<r;i++){
        //全部排名
        if(i==1){
            a[i].frank=1;
        }else{
                if(a[i].score==a[i-1].score){
                    a[i].frank=a[i-1].frank;
                }else{
                    a[i].frank=i;
                }    
        }
        //计算分组排名 
        int p=a[i].num;//他属于第p组 
        if(g_rank[p]==0){//如果他是本小组第一名 
            a[i].rank=1;
            g_rank[p]=1;//当前组排到了第几名 
            g_score[p]=a[i].score;//本小组目前排下来最后一名的分数 
            g_num[p]=1;//当前组排到了第几个人 
        }else{
            g_num[p]++;//更新人数 
            if(g_score[p]==a[i].score) {//如果此人与本组的上一人的分数相同 
                a[i].rank=g_rank[p];//就是本小组上一名的名次             
            }else{//不同的话 
                a[i].rank=g_num[p];//那么他的名次是本组的人数 
                g_rank[p]=g_num[p];//更新当前本组最后一人名次 
                g_score[p]=a[i].score;//更新分数 
            }        
        }
    }
    for(int i=1;i<r;i++){
        cout<<a[i].name<<" "<<a[i].frank<<" "<<a[i].num<<" "<<a[i].rank<<endl;
    }
    return 0;    
}

猜你喜欢

转载自www.cnblogs.com/caiyishuai/p/11361102.html