HDU2093考试排名

考试排名

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 11564    Accepted Submission(s): 4097


Problem Description
C++编程考试使用的实时提交系统,具有即时获得成绩排名的特点。它的功能是怎么实现的呢?
我们做好了题目的解答,提交之后,要么“AC”,要么错误,不管怎样错法,总是给你记上一笔,表明你曾经有过一次错误提交,因而当你一旦提交该题“AC”后,就要与你算一算帐了,总共该题错误提交了几回。虽然你在题数上,大步地跃上了一个台阶,但是在耗时上要摊上你共花去的时间。特别是,曾经有过的错误提交,每次都要摊上一定的单位时间分。这样一来,你在做出的题数上,可能领先别人很多,但是,在做出同样题数的人群中,你可能会在耗时上处于排名的劣势。
例如:某次考试一共8题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数,但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上一对括号,里面有个整数b,那就表示该学生提交该题AC了,耗去了时间a,同时,曾经错误提交了b次,因此对于下述输入数据:



若每次错误提交的罚分为20分,则其排名从高到低应该是这样的:
Josephus 5 376
John 4 284
Alice 4 352
Smith 3 167
Bob 2 325
Bush 0 0
 

Input
输入数据的第一行是考试题数n(1≤n≤12)以及单位罚分数m(10≤m≤20),每行数据描述一个学生的用户名(不多于10个字符的字串)以及对所有n道题的答题现状,其描述采用问题描述中的数量标记的格式,见上面的表格,提交次数总是小于100,AC所耗时间总是小于1000。

 

Output
将这些学生的考试现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。
 

Sample Input
  
  
8 20 Smith -1 -16 8 0 0 120 39 0 John 116 -2 11 0 0 82 55(1) 0 Josephus 72(3) 126 10 -3 0 47 21(2) -2 Bush 0 -1 -8 0 0 0 0 0 Alice -2 67(2) 13 -1 0 133 79(1) -1 Bob 0 0 57(5) 0 0 168 -7 0
 

Sample Output
  
  
Josephus 5 376 John 4 284 Alice 4 352 Smith 3 167 Bob 2 325 Bush 0 0
 
好久之前就看到这题了一直没有去做,今天去做了;题目其实就是我们平时比赛的时候RANKLIST 上面的排名的成绩 ,题目其实很简单但是做的时候真的要被自己傻哭了;

这题其实就是个多级排序,用sort()函数或者 qsort()函数都是可以写的,可以去看下这个题目中的多级排序 点击打开链接


然后就是处理数据了,所有的数据都是要用字符数组去存。每个人都有做每道题题目的可能,所以有多少道题目就意味着每个人对应着多少道题目的成绩,可以是没有AC或者压根就没有做的,也可以是一次AC的和多次提交才AC的;
那么这里我们就可以开一个结构体,用结构体来存储每个人所对应的每题的成绩,那么操作就很简单了;

排序方面就是,第一级排序是按题目的多少来排,多的在前面,少的在后面(降序排序),一样的话就看他们AC的时间了,时间少的在前面,多的在后面(升序排序),如果还是一样就按他们的字典序排序(这个可以不用管的,因为都是正常的输入)

给出AC代码和注释;
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct NODE
{
	char pro[200];
};
struct MODE
{
	char name[20];
	NODE pm[200];
	int time = 0;
	int count = 0;
	int arry;
}people[1000];
int Wrong(char str[],int m,int k,int g)//做该题所需要的时间
{
	int n = strlen(people[k].pm[g].pro);
	int a;
	int scoer = 0;
	int flag = 0;
	for (int i = 0; i < n; i++)
	{
		if (str[i] == '('){ flag = 1; a = i; break; }
	}
	if (flag == 0) //一次提交过的,直接记录AC时间就好了;
	{
		for (int i = 0; i < n; i++)
		{
			scoer = scoer * 10 + str[i] - '0';
		}
	}
	else if (flag == 1)//提交AC了,但是之前也出现过WA,所以需要罚时
	{
		int s1 = 0;
		for (int i = 0; i < a; i++)
		{
			s1 = s1 * 10 + str[i] - '0'; //提交过的时间
		}
		//cout << "s1=" << s1 << endl;
		for (int i = a + 1; str[i] != ')'; i++)
		{
			scoer = scoer * 10 + str[i] - '0'; //罚的时间
		}
		//cout << "scoer=" << scoer << endl;
		scoer = s1 + scoer * m;

	}
	return scoer;
}
bool Cmp(MODE a,MODE b)
{
	if (a.count != b.count)return a.count > b.count;  //首先按题目数量比较,如果相等则再按AC时间比较;
	else return a.time < b.time;
}
int main()
{
	int n, m;
	while (~scanf("%d%d", &n, &m))
	{
		int k, i, j;
        k = 0;
		int x = 6;
		while (~scanf("%s", people[k].name))
		//while (x--)
		{
			//scanf("%s", people[k].name);//提交的时候居然忘记把这里注释掉了,导致一直WA;
			for (i = 0; i < n; i++)
			{
				scanf("%s", people[k].pm[i].pro);
				people[i].arry = i;
				if (people[k].pm[i].pro[0] != '0'&&people[k].pm[i].pro[0] != '-')
				{
					people[k].count++;
					//cout << Wrong(people[k].pm[i].pro, m) << endl;
					people[k].time += Wrong(people[k].pm[i].pro, m,k,i);
				}
			}
			k++;
		}
		sort(people, people + k, Cmp);//排序;
		for (j = 0; j < k; j++)
		{
			printf("%-10s%3d%5d\n", people[j].name, people[j].count, people[j].time);//按题目要求控制输出格式
		}
	}
	return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值