题意
输入的数据首航是n和m,n指的是下面每个人一次做的题数,m指的是每个人每次做完一道题,括号里的每单位罚时时间。然后从下面开始,每行的输入就是一个人名,后面跟着n个分数数据,如果数据是负数或者是0,那么就不需要计算,如果是正数的话,正数代表做出这道题的时间,括号里的是做题者为了做对这道题提交这道题的次数,需要把次数乘上每单位罚时m然后加上正数,作为这个人的总罚时,然后到最后的时间就对每个人进行排序,首先是根据每个人做出题的数目降序排序,也就是每个人的正数个数,然后如果这项相同,则按总罚时升序排序,如果前两项相同,则按照名字的字母顺序排序
思路
这道题是多关键字排序,一想到多关键字就想到结构体和algorithm库的sort函数,所以我就用结构体来存储每个人的名字,做出的题数还有罚时,一开始就先申请一个1000个单位的student结构体,然后后面设计算法的时候再用一个临时变量来计算学生个数。
在输入每行数据的时候,我用一个for循环加上一个string来存储每组做题的一道题的结果,然后用字符对比,如果这个string首位是0或者是负号,则不管,如果是正数,先使得这个学生结构体的做出题数变量加一,并且一直利用ascll码字符与数字的转换规律,把其中的数字抽取并加入这个学生结构体的罚时中,最后再写个比较函数,把比较函数和这些结构体加入sort函数中进行排序。
总结
这道题主要考察多关键字排序和对每个学生的数据如何存储和读取的问题
AC代码
#include<iostream>
#include<algorithm>
#include<iomanip>
using namespace std;
struct student {
string name;
int number;//用来储存题数
int time;//用来储存罚时
student()
{
number = 0;
time = 0;
}
bool operator <(const student& p) const
{
if (number != p.number)
return number > p.number;
if (time != p.time)
return time < p.time;
return name < p.name;
}
};
student num[1000];
int main()
{
int n, m;
cin >> n >> m;
int i = 0;
string hh;
int quan = 0;
while(cin >> hh)
{
quan++;
num[i].name = hh;
for (int j = 0; j < n; j++)
{
string simple;
cin >> simple;
if (simple[0] == '-'||simple[0]=='0')
{
continue;
}
num[i].number++;
int time = 0;
int sum=0;
int k;
for (k = 0; k < simple.size(); k++)
{
if (simple[k] == '(')
{
num[i].time += sum;
sum = 0;
k++;
}
if (simple[k] == ')')
{
num[i].time += (sum * m);
break;
}
sum = (simple[k] - 48)+sum*10;
}
if (k == simple.size())
num[i].time += sum;
}
i++;
}
sort(num, num + quan);
for (int i = 0; i < quan; i++)
{
cout << resetiosflags(ios::right) << setiosflags(ios::left) << setw(10) << num[i].name << " ";
cout << resetiosflags(ios::left)<< setiosflags(ios::right) << setw(2) << num[i].number << " ";
cout <<resetiosflags(ios::left) << setiosflags(ios::right) << setw(4) << num[i].time << endl;
}
}