1012. The Best Rank (25)
To evaluate the performance of our first year CS majored students, we consider their grades of three courses only: C - C Programming Language, M - Mathematics (Calculus or Linear Algebra), and E - English. At the mean time, we encourage students by emphasizing on their best ranks -- that is, among the four ranks with respect to the three courses and the average grade, we print the best rank for each student.
For example, The grades of C, M, E and A - Average of 4 students are given as the following:
StudentID C M E A 310101 98 85 88 90 310102 70 95 88 84 310103 82 87 94 88 310104 91 91 91 91
Then the best ranks for all the students are No.1 since the 1st one has done the best in C Programming Language, while the 2nd one in Mathematics, the 3rd one in English, and the last one in average.
Input
Each input file contains one test case. Each case starts with a line containing 2 numbers N and M (<=2000), which are the total number of students, and the number of students who would check their ranks, respectively. Then N lines follow, each contains a student ID which is a string of 6 digits, followed by the three integer grades (in the range of [0, 100]) of that student in the order of C, M and E. Then there are M lines, each containing a student ID.
Output
For each of the M students, print in one line the best rank for him/her, and the symbol of the corresponding rank, separated by a space.
The priorities of the ranking methods are ordered as A > C > M > E. Hence if there are two or more ways for a student to obtain the same best rank, output the one with the highest priority.
If a student is not on the grading list, simply output "N/A".
5 6 310101 98 85 88 310102 70 95 88 310103 82 87 94 310104 91 91 91 310105 85 90 90 310101 310102 310103 310104 310105 999999Sample Output
1 C 1 M 1 E 1 A 3 A N/A
这道题目还有两个case 没有过,先把目前写的代码保存一下 ,之前的代码有一个case 是超时的,原因是我将每次输入的查询成绩的学生ID号,
都跑一遍 qsort 的算法不断更新数值进行比对,超时提醒了我,觉得这个地方完全可以在用户输入数据之后,先跑一遍4个 qsort ,然后在学生信息结构体
中增加一个属性字段,用来存储该学生的 A, C , M , E 这四个分数对应的,在各自的 sort 之后在所有的学生中排序是多少。
这种思想类似于比赛时候用到的打表的方法,先将可能查询的数据进行存储,然后等到查询的时候,再进行查找即可。
比如说,如果按照以前的想法的话,如果查找成绩的人数 为 M ,每次进行一次针对某一门特定的成绩进行排序的时间复杂度,qsort 是快排序
O(n*logn) n 是容器中等待排序的元素的个数。
那么每一个人就会花费 4*O(n*logn) 的时间, M 个待查询成绩的人,所对应的时间复杂度为 4*M*O(n*logn),
但是采用下面的类似打表的方法之后, 只要进行 4*O(n*logn) 时间复杂度既可以,对所有的N个学生中的各科课程排名字段的数值进行置位。
接下来的只要进行相应数据的查找即可。
一开始修改的地方是qsort 的四个比较方法,因为看着都觉得占地方,如果是对平均分 A 进行排序的话,那么应该是不需要对其余的数据字段 C,M,E
在进行排序的吧? 但是提交之后显然是错误的。 分数反而更低了。 后来想了一下,题目中所说的每一门课程所对应的都有各自的优先级,
这句话也不是白说的。
总之,暂时的能力只能将排序写成这种 4 个cmp 的方式,虽然看着有些不爽,但是也没有好的方法.
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <string.h>
#define A_ 0
#define C_ 1
#define M_ 2
#define E_ 3
using namespace std ;
struct node
{
char id[7] ;
int C , M , E ,A ;
int ranks[4] ;
node (){}
node ( char ID [] )
{
strcpy(id , ID ) ;
}
};
int cmp_A ( const void *a , const void *b )
{
node * x = (node*) a ;
node * y = (node*) b ;
if ( x->A < y->A )
{
return 1 ;
}
else if (x->A > y->A )
{
return 0 ;
}
else
{
if ( x->C < y->C )
{
return 1 ;
}
else if ( x->C > y->C )
{
return 0 ;
}
else
{
if ( x->M < y->M )
{
return 1 ;
}
else if (x->M > y->M)
{
return 0 ;
}
else
{
if (x->E < y->E )
{
return 1 ;
}
else
{
return 0 ;
}
}
}
}
}
int cmp_C(const void *a , const void *b )
{
node * x = (node*) a ;
node * y = (node*) b ;
if ( x->C < y->C )
{
return 1 ;
}
else if ( x->C > y->C )
{
return 0 ;
}
else
{
if ( x->M < y->M )
{
return 1 ;
}
else if (x->M > y->M)
{
return 0 ;
}
else
{
if (x->E < y->E )
{
return 1 ;
}
else
{
return 0 ;
}
}
}
}
int cmp_M( const void *a , const void *b )
{
node * x = (node*) a ;
node * y = (node*) b ;
if ( x->M < y->M )
{
return 1 ;
}
else if (x->M > y->M)
{
return 0 ;
}
else
{
if (x->E < y->E )
{
return 1 ;
}
else
{
return 0 ;
}
}
}
int cmp_E (const void *a , const void *b )
{
node *x = (node*)a ;
node *y = (node*) b ;
if (x->E < y->E )
{
return 1 ;
}
else
{
return 0 ;
}
}
node stu [2001] ;
char stuIDs [2001][7] ;
int ranks[4] , counter ;
char c[] ={'A','C','M','E'} ;
int N , M ;
void input()
{
scanf("%d%d", &N , &M ) ;
for ( int i = 0 ; i < N ; i++ )
{
scanf("%s",stu[i].id ) ;
scanf("%d%d%d", &stu[i].C , &stu[i].M , &stu[i].E) ;
stu[i].A = (stu[i].C + stu[i].M +stu[i].E)/3 ;
}
for ( int i = 0 ; i < M ; i++ )
{
scanf("%s", stuIDs[i]) ;
}
}
int getBestRank(char stuIds [] , int &rank)
{
int loc = -1 ;
int min = 99999 ;
for ( int i = 0 ; i < N ; i++ )
{
if ( strcmp(stuIds , stu[i].id)==0)
{
min = stu[i].ranks[0] ;
loc = 0 ;
for ( int j = 1 ; j < 4 ; j++ )
{
if ( min > stu[i].ranks[j] )
{
loc = j ;
min = stu[i].ranks[j] ;
}
}
break ;
}
}
rank = min ;
return loc ;
}
void rankStu( )
{
qsort( stu, N , sizeof( node ) , cmp_A) ;
for( int i = 0 ; i < N ; i++ )
{
stu[i].ranks[A_] = (i+1) ;
}
qsort( stu, N , sizeof( node ) , cmp_C) ;
for( int i = 0 ; i < N ; i++ )
{
stu[i].ranks[C_] = (i+1) ;
}
qsort( stu, N , sizeof( node ) , cmp_M) ;
for( int i = 0 ; i < N ; i++ )
{
stu[i].ranks[M_] = (i+1) ;
}
qsort( stu, N , sizeof( node ) , cmp_E) ;
for ( int i = 0 ; i < N ; i++ )
{
stu[i].ranks[E_] = (i+1 ) ;
}
}
int main ( void )
{
input() ;
rankStu() ;
for( int i = 0 ; i < M ; i++ )
{
int rank ;
int r = getBestRank(stuIDs[i] ,rank) ;
if ( r != -1 )
{
printf("%d %c", rank , c[r]) ;
}
else
{
printf("N/A") ;
}
if ( i != M-1 )
{
printf("\n") ;
}
}
return 0 ;
}