评测系统排名

问题描述

例如某次考试一共八道题(A,B,C,D,E,F,G,H),每个人做的题都在对应的题号下有个数量标记,负数表示该学生在该题上有过的错误提交次数但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上了一对括号,里面有个正数b,则表示该学生AC了这道题,耗去了时间a,同时曾经错误提交了b次。
【输入】
输入数据包含多行,第一行是共有的题数n(1≤n≤12)以及单位罚时m(10≤m≤20),之后的每行数据描述一个学生的信息,首先是学生的用户名(不多于10个字符的字串)其次是所有n道题的得分现状,其描述采用问题描述中的数量标记的格式,见上面的表格。
【输出】
根据这些学生的得分现状,输出一个实时排名。实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。
【样例输入】
8 20
Gu 96 -3 40(3) 0 0 1 -8 0
hrz 107 67 -3 0 0 82 0 0
TT 120(3) 30 10(1) -3 0 47 21(2) -2
OM 0 -99 -8 0 -666 -10086 0 -9999996
yjq -2 37(2) 13 -1 0 113(2) 79(1) -1
Zjm 0 0 57(5) 0 0 99(3) -7 0
【样例输出】
TT 5 348
yjq 4 342
Gu 3 197
hrz 3 256
Zjm 2 316
OM 0 0

问题分析

处理输入:1、由于排名制中首先考虑AC题目和罚时因素,则未通过题目对排名没有影响,因此检测如果记录分数的字符串为0或者含负号则直接跳过
2、处理括号外的数值,将每一个题的时间累加作为罚时的第一部分,与此同时累加AC题数目
3、括号内的错误提交次数单独记录*单位罚时作为罚时的另一部分
输出:自定义compare()函数,使用sort()函数(附推荐链接)
sort()函数用法

#include<iostream>
#include<iomanip>
#include<algorithm> 
using namespace std;

struct informa 
{
	string name;
	int  score;
	int  acnum;//ac数量 
    int  scoretime,scoret,scoreone;//scoret是每道ac题目的错误提交次数,scoreone是每道题的得分 
    inform()
    {
    	score=acnum=scoretime=scoret=scoreone=0;
	}
};

informa inform[100000];

//bool compare(informa a,informa b)
//{
//	if(a.acnum!=b.acnum) return a.acnum>b.acnum;
//	if(a.score!=b.score) return a.score<b.score;
//	return a.name<b.name;
//}
bool compare(informa a,informa b){
	if(a.acnum==b.acnum){
		if(a.score==b.score){
			return a.name<b.name;
		}
		return a.score<b.score;
	}
	else{
		return a.acnum>b.acnum;
	}
}
int main()
{
	int n,m;//共有的题数和单位罚时
	cin>>n>>m;
	int i=1;
	string name;
	while(cin>>name)
	{
		inform[i].name=name; 
		for(int j=0;j<n;j++)
		{
			inform[i].scoret=inform[i].scoreone=0; 
			string score;
			cin>>score;
			if(score[0]=='-'||score[0]=='0')
				continue;
			else
			{
				inform[i].acnum++;
				for(int k=0;k<score.length();k++)
				{
				    if(score[k]=='(')
				    {
				       	for(int p=k+1;p<score.length()-1;p++)
				    		inform[i].scoret=inform[i].scoret*10+(score[p]-'0'); 
				        break;
					}                              
					else
						inform[i].scoreone=inform[i].scoreone*10+(score[k]-'0');
				}
				inform[i].score+=inform[i].scoret*m+inform[i].scoreone;
			}
		}
		i++;
	}

//	//排名阶段 
//	for(int j=1;j<i-1;j++)
//	{
//		for(int k=1;k<i-j;k++)
//		{
//			if(inform[k].acnum<inform[k+1].acnum) swap(inform[k],inform[k+1]);
//			else if(inform[k].acnum==inform[k+1].acnum)
//			{
//				if(inform[k].score>inform[k+1].score)//判断罚时
//					swap(inform[k],inform[k+1]);
//				else if(inform[k].score==inform[k+1].score)
//					{
//						if(inform[k].name>inform[k+1].name)
//							swap(inform[k],inform[k+1]);
//					}
//			}
//		}
//	}	
    sort(inform+1,inform+i,compare);

	for(int j=1;j<i;j++)
	{
		cout<<std::left<<setw(10)<<inform[j].name<<" ";
		cout<<std::right<<setw(2)<<inform[j].acnum<<" ";
		cout<<std::right<<setw(4)<<inform[j].score<<endl;
	}
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值