[PAT] 1012 The Best Rank

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 Algrbra), 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 Specification:
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 Specification:
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 patpmore 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

思路:由题意得输入学生各科成绩并且计算平均分,分别对三门课及平均分进行排序,求出每个学生的最高排名(即名次最小),首先分别按照A成绩,C成绩,M成绩,E成绩分别进行降序排序,为了方便处理排名,可以用一个4容量的整型数组存取A,C,M,E的排名,然后取最小值,注意可能存在成绩一样,则排名也应该一样

代码实现:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
class Student
{
public:
	string ID;
	int C, M, E;
	double A;
	char Course;
	int rank[4];
};
bool Compare_A(Student s1, Student s2)
{
	return s1.A > s2.A;
}
bool Compare_C(Student s1, Student s2)
{
	return s1.C > s2.C;
}
bool Compare_M(Student s1, Student s2)
{
	return s1.M > s2.M;
}
bool Compare_E(Student s1, Student s2)
{
	return s1.E > s2.E;
}
int main()
{
	int N, M, i, j, tmp, cnt;
	bool flag;
	int* min;
	vector<string> ID;
	vector<Student>S;
	cin >> N >> M;
	S.resize(N), ID.resize(M);
	for (i = 0;i < N;i++)
	{
		cin >> S[i].ID >> S[i].C >> S[i].M >> S[i].E;
		S[i].A = (S[i].C + S[i].E + S[i].M ) * 1.0 / 3;
	}
	
	sort(S.begin(), S.end(), Compare_A);
	for (i = 0,tmp = 1,cnt = 1;i < N;i++)
	{
		S[i].rank[0] = tmp;
		if (i != N - 1 && S[i].A != S[i + 1].A)
		//此处涉及短路求值,即与,或运算都是先求左侧运算对象的值再求右侧运算的值
		//当且仅当左侧运算对象无法确定表达式的结果时才会计算右侧运算对象的值
		{
			tmp += cnt;
			cnt = 1;
		}
		else
		{
			cnt++;
		}
	}

	
	sort(S.begin(), S.end(), Compare_C);
	for (i = 0,tmp = 1,cnt = 1;i < N;i++)
	{	
		S[i].rank[1] = tmp;
		if (i != N - 1 && S[i].C != S[i + 1].C)
		{
			tmp += cnt;
			cnt = 1;
		}
		else
		{
			cnt++;
		}
	}
	
	sort(S.begin(), S.end(), Compare_M);
	for (i = 0,tmp = 1,cnt = 1;i < N;i++)
	{
		S[i].rank[2] = tmp;
		if (i != N - 1 && S[i].M != S[i + 1].M)
		{
			tmp += cnt;
			cnt = 1;
		}
		else
		{
			cnt++;
		}
	}

	sort(S.begin(), S.end(), Compare_E);
	for (i = 0,tmp = 1,cnt = 1;i < N;i++)
	{
		S[i].rank[3] = tmp;
		if (i != N - 1 && S[i].E != S[i + 1].E)
		{
			tmp += cnt;
			cnt = 1;
		}
		else
		{
			cnt++;
		}
	}

	for (i = 0;i < M;i++)
	{
		cin >> ID[i];
	}
	for (i = 0;i < M;i++)
	{
		flag = 0;
		for (j = 0;j < N;j++)
		{
			if (S[j].ID.compare(ID[i]) == 0)
			{
				min = min_element(S[j].rank, S[j].rank + 4);
				cout << *min << " ";
				int pos = min_element(S[j].rank, S[j].rank + 4) - S[j].rank;
				//地址-地址=整型,即数组下标,类似于指针p,p=p+1为下一元素地址
				if (pos == 0)
				{
					cout << 'A' << endl;
				}
				else if (pos == 1)
				{
					cout << 'C' << endl;
				}
				else if (pos == 2)
				{
					cout << 'M' << endl;
				}
				else if (pos == 3)
				{
					cout << 'E' <<endl;
				}
				flag = 1;
				break;
			}
		}
		if (!flag)
		{
			cout << "N/A" << endl;
		}
	}
	return 0;
}

总结:原本康到200ms就想到暴力必定超时,但是一时半会也想不到性能高的哈希表,于是先用暴力解法,第一次提交得了18分,令我惊讶的是剩下3个检测点只是答案错误,没有显示超时,因此我确信了暴力解法的可行性,后来在处理排名问题时参考他人的数组取小值算法,也算是见了新算法,同时总结出,短路求值一般可以巧妙解决vector越界问题

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值