题意:
给定一次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; }
原文地址:https://www.cnblogs.com/caiyishuai/p/11361102.html
时间: 2024-10-08 05:06:31