题意:输入数据包含多行,第一行是共有的题数n(1≤n≤12)以及单位罚时m(10≤m≤20),之后的每行数据描述一个学生的信息,首先是学生的用户名(不多于10个字符的字串)其次是所有n道题的得分现状,根据这些学生的得分现状,输出一个实时排名。其中,实时排名显然先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。每个学生占一行,输出名字(10个字符宽),做出的题数(2个字符宽,右对齐)和时间分(4个字符宽,右对齐)。名字、题数和时间分相互之间有一个空格。数据保证可按要求的输出格式进行输出。
输入格式:
8 20
GuGuDong 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
OMRailgun 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
思路:对学生进行排名,需要先计算学生们AC的题数和罚时。先建立一个结构体student,包含名字、AC数量、罚时,每次读入一个字符串str,如果str[0]是’-‘或者’0’,则不需要计算AC数和罚时,对于正数和带括号的正数,可以进行判断是否字符串里面是否由’(’,然后从字符串里面分割出数值进行计算,这时可以巧妙的利用sscanf进行分割,计算后然后利用sort排序(这时struct结构体里需要重载<运算符)。
总结:该题最主要的是对字符串进行处理分割,可以依次读取字符串的字符转成数值计算,也可以利用sscanf,sscanf对于从字符串中分割整型、浮点型都非常有用
代码:
#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct student
{ string name;
int ACNUM;
long long TIME;
bool operator<(const student& stu)const
{
if(ACNUM!=stu.ACNUM) return ACNUM>stu.ACNUM;
if(TIME!=stu.TIME) return TIME<stu.TIME;
return name<stu.name;
}
}point[1000];
int main()
{ //freopen("in.txt","r",stdin);
int n,m;cin>>n>>m;
string str;int count=0;
while(cin>>str)
{
point[count].name=str;point[count].TIME=0;point[count].ACNUM=0;
for(int i=0;i<n;i++)
{
cin>>str;
if(str[0]=='-'||str[0]=='0') continue;
int x,y;
int sumnum=sscanf(str.c_str(),"%d(%d)",&x,&y);
if(sumnum==1)
{ point[count].TIME=point[count].TIME+x;
point[count].ACNUM++;
}
else if(sumnum==2)
{
point[count].TIME=point[count].TIME+x+y*m;
point[count].ACNUM++;
}
} count++;
}
sort(point,point+count);
for(int k=0;k<count;k++)
{
printf("%-10s %2d %4lld\n",point[k].name.c_str(),point[k].ACNUM, point[k].TIME);
} return 0;
}
来源:CSDN
作者:_Distant
链接:https://blog.csdn.net/qq_45757204/article/details/104635416