//直接用c++ algorithm头文件中sort()函数排序,真好用!!
//sort是不稳定的排序。不可以先对注册号排序,再对分数排序来实现同分数的按注册号递增
//思路是sort既可以对整个数组排序,也可以对数组中的一部分排序
//所以我把所有考场的学生都放在一个stu数组里面,每个考场在stu里都有一个开始下标st和结尾下标ed
//用sort(stu+st,stu+ed,/按分数排序函数/)就可以对这个考场的人排序
//排完序后for(int i=st;i<ed;i++)扫描一遍计算出每个学生在考场里的排名(如果和前一个学生分数相等,排名就和前一个学生一样,如果不等,排名就等于i-st+1)
//最后在sort(stu,stu+totalNum,/按分数排序函数/)来对所有人排序
//排完序后再扫描一遍整个stu,计算每个学生的总排名,顺便把排名相同的人按注册号排一次序
//OK,直接输出stu,万事大吉!~
//ac
#include<stdlib.h>
#include<stdio.h>
#include<cstring>
#include<algorithm>
#define MAXN 100
#define MAXK 300
using namespace std;
struct Student{
char regist[14]; //注册号
int score; //分数
int locNum; //考场号
int oldIdx; //考场里的排名
int newIdx; //总排名
};
Student* stu[MAXN*MAXK]; //所有考场的考生都存储在这一个数组中
bool cmpByNo(Student* a,Student *b){ //按注册号递增排序,详情请搜索sort函数的应用
return strcmp(a->regist,b->regist) <=0;
}
bool cmpByScore(Student* a,Student* b){ //按分数递减排序
return a->score > b->score;
}
void fillOldIndex(int st,int ed){ //计算学生在考场里的排名
stu[st]->oldIdx=1;
for(int i=st+1;i<ed;i++){
if(stu[i]->score==stu[i-1]->score){
stu[i]->oldIdx=stu[i-1]->oldIdx;
}else{
stu[i]->oldIdx=i-st+1;
}
}
}
void fillNewIndex(int size){ //计算学生的总排名
int i=0;
while(i!=size){
int st=i;
stu[i]->newIdx=i+1;
while(i+1!=size&&stu[i]->score==stu[i+1]->score){ //每次向后找所有分数相同的人
stu[i+1]->newIdx=stu[i]->newIdx;
i++;
}
i++;
sort(stu+st,stu+i,cmpByNo); //分数相同的人要按注册号排一次序
}
}
int main(){
int N;
scanf("%d",&N);
int st=0;
int ed=0;
for(int i=0;i<N;i++){
int k;
scanf("%d",&k);
st=ed;
ed=st+k;
for(int j=st;j<ed;j++){
stu[j]=(Student*)malloc(sizeof(Student));
scanf("%s %d",stu[j]->regist,&stu[j]->score);
stu[j]->locNum=i+1;
}
sort(stu+st,stu+ed,cmpByScore);
fillOldIndex(st,ed);
}
sort(stu,stu+ed,cmpByScore);
fillNewIndex(ed);
printf("%d\n",ed);
for(int i=0;i<ed;i++){
printf("%s %d %d %d\n",stu[i]->regist,stu[i]->newIdx,stu[i]->locNum,stu[i]->oldIdx);
}
}
感谢大家耐着性子看我的代码,不足之处,请多指教^_^