一、概述
给出N个学生的各科成绩,输出该学生的单科最好成绩。
我使用了多次sort实现。坑点在于三个学生的分数若为80,80,90,则名次应该是1,2,2,而不是1,2,3.选择后者测试点1和2过不去。
二、分析
既然要输入最好成绩,那么便需要根据每门成绩排序一次,共排序四次。因此我使用结构存储学生的ID,各科成绩和各科排名。如下:
struct Student
{
char ID[6];
int C, M, E, A;
int rank[4];
}student[2000];
注意rank数组是用于存储单科成绩的,因为当成绩相同时,各科优先级顺序为A,C,M,E,那么rank数组也按这个顺序,这样一来,在最后选择rank数组的最小值时,自动保存最前面的最小值。也就自动按照优先级排序了。
排序四次,因此需要四个cmp函数,如下:
bool cmpC(Student a, Student b)
{
return a.C > b.C;
}
bool cmpM(Student a, Student b)
{
return a.M > b.M;
}
bool cmpE(Student a, Student b)
{
return a.E > b.E;
}
bool cmpA(Student a, Student b)
{
return a.A > b.A;
}
四个sort函数如下:
sort(student, student + N, cmpA);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].A == student[i - 1].A)
student[i].rank[0] = student[i - 1].rank[0];
else
student[i].rank[0] = i;
}
else
student[i].rank[0] = i;
}
sort(student, student + N, cmpC);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].C == student[i - 1].C)
student[i].rank[1] = student[i - 1].rank[1];
else
student[i].rank[1] = i;
}
else
student[i].rank[1] = i;
}
sort(student, student + N, cmpM);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].M == student[i - 1].M)
student[i].rank[2] = student[i - 1].rank[2];
else
student[i].rank[2] = i;
}
else
student[i].rank[2] = i;
}
sort(student, student + N, cmpE);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].E == student[i - 1].E)
student[i].rank[3] = student[i - 1].rank[3];
else
student[i].rank[3] = i;
}
else
student[i].rank[3] = i;
}
sort下面的四个循环用于存储对应名次,在名次相同时的处理一定要注意。
接下来对照输入选择对应的学生的rank中的最小值输出即可,这可真绕。
我使用char存的ID,因此使用strcmp函数,注意vs2015使用string头文件即可,但是oj要求使用cstring。
另外,由于只要求比较平均数的大小而不要求输出平均数,为了避免四舍五入的麻烦,直接比较和就可以,而不用再除以三。
这是题目出的不严谨的一个地方。
三、总结
对于sort和cmp应用很好的一道题。
PS:代码如下:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
struct Student
{
char ID[6];
int C, M, E, A;
int rank[4];
}student[2000];
bool cmpC(Student a, Student b)
{
return a.C > b.C;
}
bool cmpM(Student a, Student b)
{
return a.M > b.M;
}
bool cmpE(Student a, Student b)
{
return a.E > b.E;
}
bool cmpA(Student a, Student b)
{
return a.A > b.A;
}
int main()
{
int N, M;
scanf("%d %d", &N, &M);
int i;
for (i = 0; i < N; i++)
{
scanf("%s %d %d %d", &student[i].ID, &student[i].C, &student[i].M, &student[i].E);
student[i].A = student[i].C + student[i].M + student[i].E;
}
sort(student, student + N, cmpA);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].A == student[i - 1].A)
student[i].rank[0] = student[i - 1].rank[0];
else
student[i].rank[0] = i;
}
else
student[i].rank[0] = i;
}
sort(student, student + N, cmpC);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].C == student[i - 1].C)
student[i].rank[1] = student[i - 1].rank[1];
else
student[i].rank[1] = i;
}
else
student[i].rank[1] = i;
}
sort(student, student + N, cmpM);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].M == student[i - 1].M)
student[i].rank[2] = student[i - 1].rank[2];
else
student[i].rank[2] = i;
}
else
student[i].rank[2] = i;
}
sort(student, student + N, cmpE);
for (i = 0; i < N; i++)
{
if (i > 0)
{
if (student[i].E == student[i - 1].E)
student[i].rank[3] = student[i - 1].rank[3];
else
student[i].rank[3] = i;
}
else
student[i].rank[3] = i;
}
int j, k;
for (i = 0; i < M; i++)
{
char _ID[6];
scanf("%s", &_ID);
int TOF = 0;
for (j = 0; j < N; j++)
{
if (strcmp(_ID, student[j].ID) == 0)
{
TOF = 1;
int min = 2000;
int sub = -1;
for (k = 0; k < 4; k++)
{
if (student[j].rank[k] < min)
{
min = student[j].rank[k];
sub = k;
}
}
switch (sub)
{
case 0:
printf("%d A\n", min+1);
break;
case 1:
printf("%d C\n", min+1);
break;
case 2:
printf("%d M\n", min+1);
break;
case 3:
printf("%d E\n", min+1);
break;
}
}
}
if (TOF == 0)
printf("N/A\n");
}
}