学长的那些事系列之–暑期集训
题目描述
暑期集训是学长提升自己的最佳时间段,在集训期间会举办多次排位赛,学长们之间竞争相当激烈,每次比赛名次变化都很大。经过一个暑假在训练和比赛,学长的最终排名是什么呢?
输入
第一行输入两个整数m、n,m表示参加集训的学长的人数(m<50),n表示集训期间排位赛的次数(n<20);
下面输入n行整数,每行m个数,表示m个学长在每次比赛中做出的题目数,题目数小于15。
输出
输出学长的最终名次,排名规则是按每次比赛的名次相加,数值小的名次在前。
样例输入
3 2
5 2 6
3 3 4
样例输出
2 3 1
提示
名次可以相同,相同名次后面的人的名次间隔开。例如:第1名两个人,随后人的名次是3。
代码
#include <iostream>
#include <algorithm>
using namespace std;
struct per{
int num;
int total;
};//序号与得分结构体
per stu[50],race[50];//stu本轮做题量,race本轮名次
int m,n,rrace[50];//m人,n轮,rrace最终排名累加
bool cmp(per a,per b){//从大到小排序
return a.total>b.total;
}
bool cmp1(per a,per b){//从小到大排序
return a.total<b.total;
}
void set(per p[]){//结构体初始化
for(int i=0;i<m;i++){
p[i].num=i;
p[i].total=0;
}
}
int main(){
scanf("%d%d",&m,&n);
set(race);//初始化本轮名次
for(int i=0;i<n;i++){
set(stu);//初始化本轮得分
for(int j=0;j<m;j++){
scanf("%d",&stu[j].total);//输入本轮得分
}
sort(stu,stu+m,cmp);//得分排序
//根据得分排名次
int r=1;//记录并列值
for(int j=0;j<m;j++){
if(j==0){
race[stu[j].num].total+=j+1;//最大的名次j+1=1
r=j+1;
}
else{
if(stu[j].total==stu[j-1].total){
race[stu[j].num].total+=r;//与前一个并列
r=r;
}
else{
race[stu[j].num].total+=j+1;//没有并列
r=j+1;
}
}
}
}
sort(race,race+m,cmp1);//总排名从小到大
for(int i=0;i<m;i++){
if(i==0){
rrace[race[i].num]=i+1;//最小的是第一名
}
else{
if(race[i].total==race[i-1].total){
//与上一个相等,并列
rrace[race[i].num]=rrace[race[i-1].num];
}
else{
//非并列
rrace[race[i].num]=i+1;
}
}
}
for(int i=0;i<m;i++){
printf("%d ",rrace[i]);//输出
}
return 0;
}