有处罚机制的实时评测系统
例如某次考试一共八道题(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。