HDU-2093 || 有处罚机制的实时评测系统

有处罚机制的实时评测系统

例如某次考试一共八道题(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个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。

Sample Input:
在这里插入图片描述

Sample Output
在这里插入图片描述

解题思路

我个人认为这道题的难点在于如何将数据分开,用cin将数字给获取后,再用getchar把数字后面的字符给抓取过来比较,如果是左括号,那么就进入另一个判断。

代码部分
#include<iostream>
using namespace std;
#include<stdio.h>
#include <algorithm>

#include<cstring>
struct P          
{
	char name[10];    //名字
	int ac;          //ac题目的个数
	int time;       //罚时
	
	bool operator<(const P& p)   //重载
	{
		if(ac!=p.ac)  return ac>p.ac;
		if(time!=p.time) return time<p.time;
		  return  name[0] < p.name[0];
	}
};

P pp[5000];

int main()
{
	int pi=0;
	int n,m;
	cin>>n>>m;

	int a;
	int aci=0;
	int time=0;
	while( cin>>pp[pi].name )   
	{
		for(int i=0;i<n;i++)
		{
			cin>>a;
			if(a>0)             //如果是正数,就正常增加
			{
				aci++;
				time+=a;
			}
			char c=getchar();  
			if(c=='(')           //进入括号
			{
				int b;
				cin>>b;
				time += b*m;
				c = getchar();  
			}
		}	
		pp[pi].ac = aci;        //给这位同学赋值
			pp[pi].time=time;
			aci=0;time=0;
			pi++;
		
	}
	sort(pp,pp+pi);           //对结构体数组排序
	for(int i=0;i<pi;i++)
	{
		printf("%-10s ",pp[i].name);
		printf("%2d ",pp[i].ac);
		printf("%4d\n",pp[i].time);
	}
	return 0;
}

收获
其实这一题比较困难的点在于怎么读取数据,我一开始也卡了很久,想用string把一整行的数据都提取出来,再用sscanf进行提取,分配到 m 个 变量中去,但是搞了好久都没有成功,后来才用cin读取(问了同学) ,cin 只读了整数这种操作我是没有想到的。后来上课的时候才知道sscanf是可以提取的,只不过不是提取一整行,而是提取一个,比如if(sscanf(a,"%d(%d)",&b,&c) ) ==1 这样提取,这种操作是真的强,我是真的没有想到这样用sscanf。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值