例如某次考试一共八道题(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
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
Sample Output
TT 5 348
yjq 4 342
GuGuDong 3 197
hrz 3 256
Zjm 2 316
OMRailgun 0 0
分析:唯一难点在于读入99(3)这样的数据
方法一:判断读入的字符是否包含‘(’若为真,用substr截取括号内外两个数,
cin >> inputStr;
int index = inputStr.find('(');
if (index != string::npos)
{
string s1 = inputStr.substr(0, index);
int index2 = inputStr.find(')');
string s2 = inputStr.substr(index + 1, index2 - index - 1);
theStudent.ac++;
theStudent.score += (stoi(s2) * s + stoi(s1));
}
else
{
if (stoi(inputStr) > 0)
{
theStudent.ac++;
theStudent.score += stoi(inputStr);
}
}
方法二:利用格式化输入sscanf()。
修改后完整代码如下:
#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <string>
using namespace std;
struct student
{
string name;
int ac;
int score;
};
vector<student> students;
int main()
{
int n, m;
cin >> n >> m;
string name;
while (cin >> name)
{
student theStudent;
theStudent.name = name;
theStudent.ac = 0;
theStudent.score = 0;
string s;
for (int i = 0; i < n; i++)
{
cin >> s;
int x, y;
if (sscanf(s.c_str(), "%d(%d)", &x, &y) == 1)
{
theStudent.ac += (x > 0);
theStudent.score += x > 0 ? x : 0;
}
else
{
theStudent.ac++;
theStudent.score += (x + y * m);
}
}
students.push_back(theStudent);
}
sort(students.begin(), students.end(), [](const student& lhs, const student& rhs) {
if (lhs.ac != rhs.ac) return lhs.ac > rhs.ac;
if (lhs.score != rhs.score) return lhs.score < rhs.score;
return lhs.name < rhs.name;
});
for (vector<student>::iterator c = students.begin(); c != students.end(); c++)
cout << setw(10) << left << c->name << ' ' <<
setw(2) << right << c->ac << ' '
<< setw(4) << right << c->score << endl;
}