pat1012

19 篇文章 0 订阅

1012. The Best Rank (25)

时间限制   400 ms    内存限制    32000 kB   代码长度限制    16000 B

判题程序   Standard   作者   CHEN, Yue

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".


Sample Input
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
999999
Sample 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 ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值