实验成绩排名

问题描述:

某些实验使用的实时评测系统,具有及时获得成绩排名的特点,那它的功能是怎么实现的呢?
在岁月的长河中,你通过的题数虽然越来越多,但通过每题时你所共花去的时间(从最开始算起,直至通过题目时的这段时间)都会被记录下来,作为你曾经奋斗的痕迹。特别的,对于你通过的题目,你曾经的关于这题的每次错误提交都会被算上一定的单位时间罚时,这样一来,你在做出的题数上,可能领先别人很多,但是在做出同样题数的人中,你可能会因为罚时过高而处于排名上的劣势。
例如某次考试一共八道题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上了一对括号,里面有个正数b,则表示该学生AC了这道题,耗去了时间a,同时曾经错误提交了b次。

input:
输入数据包含多行,第一行是共有的题数n(1≤n≤12)以及单位罚时m(10≤m≤20),之后的每行数据描述一个学生的信息,首先是学生的用户名(不多于10个字符的字串)其次是所有n道题的得分现状,其描述采用问题描述中的数量标记的格式。
output:
根据这些学生的得分现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。

解题思路:

首先我们可以根据输入来判断,我们首先要输入一个名字,那么我们可以使用string变量来保存这个名字,然后其后跟这一系列的数字,有正的,有负的,还有带小括号的,那么我们可以每一次读一个整形,只有读入的数为正数,才对其进行操作,然后通过一个getchar()来读入一个字符,判断数字后面还有没有括号,若有,对其进行处理,处理结束后再使用一个getchar将另一个括号读入,以免影响其后的操作。

再解决了数据读入的问题之后,接下来就要考虑数据存储,根据输出,输出一个学生的名字。AC题目多少,和所用的时间,那我们就能用一个结构体来存储每一个学生的信息,并且为了方便排序,我们在结构体中重载了"<"。

在所有数据都读入之后,还要进行排序,则我们用到了algorithm中的sort函数,按照多关键字对其进行排序,然后进行输出。

解题总结:

对于这种有复杂输入的题目,我们要考虑清楚每一个数据要用什么变量来存储,以及遇到一些特殊情况怎么来处理,那么问题基本就解决了。

代码:

#include<cstdio>
#include<iostream>
#include<string>
#include<iomanip>
#include<algorithm>
using namespace std;
struct student {  //结构体
	string name;
	int num;
	int time;
	//重载小于号。第一字典序降序,第二字典序升序,第三字典序升序
	bool operator < (student& ss) { 
		if (num != ss.num) return num > ss.num;
		if (time != ss.time) return time < ss.time;
		return name < ss.name;
	}
};
student ts[10000]; 
int all; //学生个数
int main()
{
	all = -1;
	int n, m;
	cin >> n >> m;
	string info;
	while (cin >> info)
	{
		all++;
		ts[all].name = info;
		ts[all].num = 0;
		ts[all].time = 0;
		char abc;
		for (int i = 0; i < n; i++)
		{
			int hh;
			cin >> hh;  //读入成绩
			if (hh < 0)
			{
				continue;
			}
			else if (hh == 0)
			{
				continue;
			}
			else if (hh > 0)  //当成绩大于0时才处理
			{
				ts[all].num++;
				int flag = 0;
				flag = flag + hh;
				char bb = getchar();
				if (bb == '(') //判断其后是否有圆括号
				{
					int vcc;
					cin >> vcc;
					flag = flag + vcc * m;
					getchar();
				}

				ts[all].time = ts[all].time + flag;
			}
		}

	}
	sort(ts, ts + all + 1); //排序
	for (int i = 0; i <= all; i++)  //输出
	{
		cout << setiosflags(ios::left) << setw(10) << ts[i].name << " ";
		cout << setiosflags(ios::right) << setw(2) << ts[i].num << " ";
		cout << setiosflags(ios::right) << setw(4) << ts[i].time << "\n";
		cout << resetiosflags(ios::right);
	}
	return 0;
}
发布了21 篇原创文章 · 获赞 4 · 访问量 911

猜你喜欢

转载自blog.csdn.net/zhL816/article/details/104639080