题意
给你一个n和一个l分别为考生人数和最高级别,接下来n行写出考生的准考证号和成绩。要求从高到低输出每位考生的证书信息,若是0 分即为无证书,按字典序输出准考证号即可
思路
1.需要进行排序,若分数相同则按序号小从小到大排,若不相同则按分数从大到小排
2.按照要求进行模拟
坑点
1.排名,若有3个第一名,下一名的排名为3+1名,并且排名是在<=当前级别的所有人中的排名
代码
#include<bits/stdc++.h>
using namespace std;
int cj[6]={0,30,50,60,80,100};//存储各级别的最高分
const int N=1e5+10;
struct name{
string s;//准考证号
int fs;//分数
int dj;//级别
}a[N];
bool cmp(name x,name y)//排序
{
if(x.fs==y.fs)//分数相同
{
return x.s<y.s;//按照级别从小到大进行排序
}
else{
return x.fs>y.fs;//按照分数从大到小进行排序
}
}
int main()
{
int n,l;
cin>>n>>l;//输入总人数 和最高级别
vector<int>v[6];
for(int i=1;i<=n;i++)
{
cin>>a[i].s>>a[i].fs;//遍历输入编号和分数
}
sort(a+1,a+1+n,cmp);//排序
for(int i=1;i<=n;i++)//再次进行遍历
{
if(a[i].fs>80)//若分数大于80
{
a[i].dj=5;//级别为5
v[5].push_back(i);//存入当前的等级
}
else if(a[i].fs>60)//若分数>60
{
a[i].dj=4;//级别为4
v[4].push_back(i);//存入当前的等级
}
else if(a[i].fs>50)//若分数大于 50
{
a[i].dj=3;//级别为3
v[3].push_back(i); //存入
}
else if(a[i].fs>30)//若分数大于30
{
a[i].dj=2;//级别为2
v[2].push_back(i);//存入
}
else if(a[i].fs>0)//分数大于0
{
a[i].dj=1;//级别为1
v[1].push_back(i);//存入
}
else{
v[0].push_back(i);//分数为0 也存入
}
}
for(int i=1;i<=n;i++)
{
if(a[i].fs!=0)//首先分数不为0时
{
cout<<a[i].s<<" "<<a[i].dj<<" "<<a[i].fs<<"/"<<cj[a[i].dj]<<" ";//输出对应第一名编号 等级 分数/级别总分
int sum=0,cnt=1;
for(int j=0;j<=a[i].dj;j++)
{
sum+=v[j].size();//求出当前级别及以下共有多少人
}
int f=(n-sum)+1;//第一级别以下的总人数
for(int k=f;k<=n;k++)
{
if(a[k].fs>a[i].fs)//自己都比谁大
{
cnt++;//自己所在的排名
}
}
cout<<cnt<<"/"<<sum<<endl;//输出排名及总人数
}
else{
cout<<a[i].s<<endl;//0分的输出自己的编号
}
}
return 0;
}
总结
难度稍难,细节较多,需细心判断