大致思路:先预处理,对每个学生,将其各科成绩名次存储在结构体中,然后对某个要查找的学生,对其rank数组进行二次打擂台
第一次打擂台求出该学生的最高名次,第二次打擂台求出最高名次中的最大权值的课程
需要注意,在给某科目排序时,成绩相同的名次一致,若不注意这点,测试不能通过
本题还可以优化减少代码量,不用写多个cmp函数,也不用写多个sort,也可以不用map存储课程与权值的映射,直接用一维数组下标对应权值
总体来说不是很难,排序的一道典型题
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
#include<iostream>
#include<map>
#define inf 1000
using namespace std;
map<char,int>hashtable;
struct Rank//表示课程s以及对应的名次
{
char s;
int r;
};
struct stu
{
int C;
int M;
int E;
int A;
string num;
stu(int c,int m,int e,string t):C(c),M(m),E(e),num(t){
}
vector<Rank>R;//存储了该学生四门课程以及其对应名次
};
vector<stu>s;
bool cmp1(stu a,stu b)//按c的成绩排
{
return a.C>b.C;
}
bool cmp2(stu a,stu b)
{
return a.M>b.M;
}
bool cmp3(stu a,stu b)
{
return a.E>b.E;
}
bool cmp4(stu a,stu b)
{
return a.A>b.A;
}
int n,m;
void findmax(stu a)
{
int toprank=inf;
for(int i=0;i<a.R.size();i++){
//先找到某学生的最高名次
if(a.R[i].r<toprank){
toprank=a.R[i].r;
}
}
char sub='E';
for(int i=0;i<a.R.size();i++){
//找到某学生获得最高名次的若干课程中,权值最大的课程
if(a.R[i].r==toprank){
char s=a.R[i].s;
if(hashtable[s]>hashtable[sub]){
sub=s;
}
}
}
printf("%d %c\n",toprank,sub);//输出最高名次和最大权值的课程
}
int main()
{
scanf("%d %d",&n,&m);
hashtable['A']=4;//对课程进行权重的映射
hashtable['C']=3;
hashtable['M']=2;
hashtable['E']=1;
while(n--){
string temp;
int c,m,e;
cin>>temp;
scanf("%d %d %d",&c,&m,&e);
stu t(c,m,e,temp);
t.A=(c+m+e)/3;
s.push_back(t);//初始化数据
}
sort(s.begin(),s.end(),cmp1);
for(int i=0;i<s.size();i++){
//对所以学生按课程c的成绩进行排序,并将名次存入对应学生结构体中
Rank temp;
temp.s='C';//万恶之源在此!!!!
if(i>0&&s[i].C==s[i-1].C){
temp.r=temp.r;
}
else{
temp.r=i+1;
}
s[i].R.push_back(temp);
}
sort(s.begin(),s.end(),cmp2);
for(int i=0;i<s.size();i++){
Rank temp;
temp.s='M';
if(i>0&&s[i].M==s[i-1].M){
temp.r=temp.r;
}
else{
temp.r=i+1;
}
s[i].R.push_back(temp);
}
sort(s.begin(),s.end(),cmp3);
for(int i=0;i<s.size();i++){
Rank temp;
temp.s='E';
if(i>0&&s[i].E==s[i-1].E){
temp.r=temp.r;
}
else{
temp.r=i+1;
}
s[i].R.push_back(temp);
}
sort(s.begin(),s.end(),cmp4);
for(int i=0;i<s.size();i++){
Rank temp;
temp.s='A';
if(i>0&&s[i].A==s[i-1].A){
temp.r=temp.r;
}
else{
temp.r=i+1;
}
s[i].R.push_back(temp);
}
while(m--){
string num;
cin>>num;
int flag=1;
for(stu x:s){
if(x.num==num){
findmax(x);
flag=0;
}
}
if(flag==1){
//没查找到
printf("N/A\n");
}
}
return 0;
}