题目大意:各考生的 C 程序设计、数学、英语成绩已知,并可以算出平均分(计算总分即可),各门课和总成绩共 4 项成绩单独排名,询问各学生在这 4 项排名中的最高名次和对应科目输出;如果最高排名有多个,则输出按照 总分 > C程序设计 > 数学 > 英语 的优先级至多选取一门课输出。
解题思路:本题就是暴力模拟,采用结构体存储信息。用 map 记住名字对应的输入顺序号,避免之后的查找;然后就是 4 个排序,计算各门课的排行,用相应的记号来记录(注意排名的处理,比如并列第一有两个,那么分第二高的就是第三名......);还原结构体,进行询问。PS:代码不优美,勿喷~~
题目链接:https://www.patest.cn/contests/pat-a-practise/1012
#include <iostream>
#include <algorithm>
#include <set>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <cstring>
using namespace std;
typedef struct stuInfo{
char name[15];
int a,c,m,e,id;
int rankA,rankC,rankM,rankE;
}stuInfo;
stuInfo stu[10005],stuCopy[10005];
map<string,int> nameToNum;//记住 id 对应 name,避免顺序查找
bool cmp1(stuInfo x1,stuInfo x2)
{
if(x1.a > x2.a)
return true;
return false;
}
bool cmp2(stuInfo x1,stuInfo x2)
{
if(x1.c > x2.c)
return true;
return false;
}
bool cmp3(stuInfo x1,stuInfo x2)
{
if(x1.m > x2.m)
return true;
return false;
}
bool cmp4(stuInfo x1,stuInfo x2)
{
if(x1.e > x2.e)
return true;
return false;
}
int main(int argc, char** argv) {
int n,m;
cin >> n >> m;
for(int i=0;i<n;++i)
{
scanf("%s %d %d %d",&stu[i].name,&stu[i].c,&stu[i].m,&stu[i].e);
stu[i].a = (stu[i].c+stu[i].m+stu[i].e);
stu[i].id = i;
nameToNum[stu[i].name] = i;
}
//Average
sort(stu,stu+n,cmp1);
stu[0].rankA = 1;
for(int i=1;i<n;++i)
{
if(stu[i].a != stu[i-1].a)
{
stu[i].rankA = i+1;
}
else
{
stu[i].rankA = stu[i-1].rankA;
}
}
// C Programming
sort(stu,stu+n,cmp2);
stu[0].rankC = 1;
for(int i=1;i<n;++i)
{
if(stu[i].c != stu[i-1].c)
{
stu[i].rankC = i+1;
}
else
{
stu[i].rankC = stu[i-1].rankC;
}
}
//Mathematics
sort(stu,stu+n,cmp3);
stu[0].rankM = 1;
for(int i=1;i<n;++i)
{
if(stu[i].m != stu[i-1].m)
{
stu[i].rankM = i+1;
}
else
{
stu[i].rankM = stu[i-1].rankM;
}
}
//English
sort(stu,stu+n,cmp4);
stu[0].rankE = 1;
for(int i=1;i<n;++i)
{
if(stu[i].e != stu[i-1].e)
{
stu[i].rankE = i+1;
}
else
{
stu[i].rankE = stu[i-1].rankE;
}
}
//还原
for(int i=0;i<n;++i)
{
stuCopy[stu[i].id] = stu[i];
}
for(int i=0;i<m;++i)
{
char a[15];
cin >> a;
if(nameToNum.count(a) == 0)
{
cout << "N/A" << endl;
continue;
}
int pos = nameToNum[a];
int rA,rC,rM,rE;
rA = stuCopy[pos].rankA;
rC = stuCopy[pos].rankC;
rM = stuCopy[pos].rankM;
rE = stuCopy[pos].rankE;
int Min = min(min(rA,rC),min(rM,rE));
cout << Min;
if(Min == rA)
cout << " A" << endl;
else if(Min == rC)
cout << " C" << endl;
else if(Min == rM)
cout << " M" << endl;
else if(Min == rE)
cout << " E" << endl;
}
return 0;
}