大力出奇迹

例如某次考试一共八道题(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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值