题目
题目描述
高考成绩的排名规则是按总分由高到低排,总分相同的人排名应相同,例如有 5 个同学的考高成绩:
考号 姓名 成绩 001 c1 567 002 ygh 605 003 gl 690 004 xtb 605 005 wzs 567 按照成绩排序后,成绩如下:
排名 考号 姓名 成绩 1 003 gl 690 2 002 ygh 605 004 xtb 3 001 cl 567 005 wzs 现在给出 n 个同学的高考成绩信息,请你回答查询:考号为 xxx 的学生排名是多少。
输入格式
第一行含一个整数 n,表示学生人数。
接下来的 n 行,每行表示一个学生信息:考号(长度为 6 的数字串),姓名(长度不超过 10,且不空格的字符串),成绩(是在 0..750 之间的整数)。
第 n+2 行为一个整数 m,表示有 m 次查询。接下来的 m 行,每行是一个考号信息
输出格式
包含 m 行,对应输入中的查询。如果找到对应考号的学生,输出其姓名和名次,否则输出“Test error number!”。
样例
样例输入
5 001 cl 567 002 ygh 605 003 gl 690 004 xtb 605 005 wzs 567 3 003 001 006
样例输出
gl 1 cl 3 Test error number!
数据范围与提示
分析
看看这道题的数据范围:100000!!!
震惊到了,有没有种可能,暴力枚举会超时?今天我们就来给你们证明一下“暴力出奇迹”!!
struct str{
long long node,score;
string name;
}a[MAX];
struct str1{
bool flag=false;
long long score1;
string name;
}b[MAX];
一开始,我定义了两个结构体,一个用于输入,一个用于储存。
for(int i=1;i<=n;i++){
cin>>a[i].node>>a[i].name;
cin>>a[i].score;
b[a[i].node].name=a[i].name;
b[a[i].node].score1=a[i].score;
b[a[i].node].flag=true;
}
接着,我们输入每一个人的学号,名字,和分数,并把它们存到b数组里边,以遍后面好统计。我设立flag的作用是在后面判断有没有这个学号出现。
sort(a+1,a+1+n,cmp);
bool cmp(str x,str y){
return x.score>y.score;
}
这里是排序加上cmp排序函数,就不用我多说了吧。
for(int i=1;i<=n;i++){
if(a[i].score!=a[i-1].score){
cnt++;
mark[a[i].score]=cnt;
}
}
这一块的作用其实就是把分数一样的人合并起来(题目要求)。
for(int i=1;i<=m;i++){
cin>>c[i];
if(b[c[i]].flag==true){
cout<<b[c[i]].name<<" "<<mark[b[c[i]].score1]<<endl;
}else{
cout<<"Test error number!"<<endl;
}
}
我们之前所提到的flag现在终于发挥作用了!!这一段就是判断是否存在这个学号,如果存在就输出名字和名次,如果不在,就按照题目输出。
接下来我们放上参考代码:
参考代码
#include<bits/stdc++.h>
using namespace std;
const int MAX=1000005;
typedef long long ll;
long long n,m,mark[MAX],cnt;
long long c[MAX];
struct str{
long long node,score;
string name;
}a[MAX];
struct str1{
bool flag=false;
long long score1;
string name;
}b[MAX];
bool cmp(str x,str y){
return x.score>y.score;
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].node>>a[i].name;
cin>>a[i].score;
b[a[i].node].name=a[i].name;
b[a[i].node].score1=a[i].score;
b[a[i].node].flag=true;
}
sort(a+1,a+1+n,cmp);
cin>>m;
for(int i=1;i<=n;i++){
if(a[i].score!=a[i-1].score){
cnt++;
mark[a[i].score]=cnt;
}
}
for(int i=1;i<=m;i++){
cin>>c[i];
if(b[c[i]].flag==true){
cout<<b[c[i]].name<<" "<<mark[b[c[i]].score1]<<endl;
}else{
cout<<"Test error number!"<<endl;
}
}
return 0;
}
好了,我们今天的题就讲到这里,咋们下次再见ヾ( ̄▽ ̄)Bye~Bye~