前言

传送门

正文

参考思路

基本排序题,需要注意的是pre和curr的妙处,分别记录当前成绩单中第一个成绩和最后一个成绩在整个合并成绩单中的下标

参考题解

#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
/*
合并排名表,根据输出来确定结构体中的成员变量有 id,grade,
final_rank,location和local_rank , pre和curr分别记录每个成绩表中
第一个成绩的下标和最后一个成绩的下标 。 
*/
struct student{
	char id[15];
	int grade,final_rank,location,local_rank; 
}stus[30010];
//排序规则
bool cmp(student a,student b){
	if(a.grade!=b.grade)return a.grade>b.grade;
	else return strcmp(a.id,b.id)<0;
} 

int main(){
	int n,k,pre=0,curr=-1;//pre和curr分别记录每个成绩表中第一个成绩的下标和最后一个成绩的下标 
	scanf("%d",&n);
	for(int i=0;i<n;i++){//读入n个成绩表 
		scanf("%d",&k);
		for(int j=0;j<k;j++){//每个成绩表中的k条成绩 
			curr++;
			scanf("%s %d",stus[curr].id,&stus[curr].grade);
			stus[curr].location=i+1;//成绩所属成绩表 
		}
		sort(stus+pre,stus+curr+1,cmp);//对当前成绩表的中成绩进行排名,计算local_rank 
		stus[pre].local_rank=1;//当前成绩表的第一个成绩记录的local_rank为1 
		for(int t=1;t<k;t++){
			if(stus[pre+t].grade==stus[pre+t-1].grade)stus[pre+t].local_rank=stus[pre+t-1].local_rank;
			else stus[pre+t].local_rank=t+1;
		}
		pre=curr+1;
	}
	sort(stus,stus+curr+1,cmp);//对所有成绩记录进行总的排名,计算final_rank 
	stus[0].final_rank=1; 
	printf("%d\n",curr+1);//成绩记录的总数 
	for(int i=1;i<=curr;i++){
		if(stus[i].grade==stus[i-1].grade)stus[i].final_rank= stus[i-1].final_rank;
		else stus[i].final_rank=i+1;
	}
	for(int i=0;i<=curr;i++){
		printf("%s %d %d %d\n",stus[i].id,stus[i].final_rank,stus[i].location,stus[i].local_rank);
	}
	
	return 0;
}