Week2 实验B 成绩排名

  • 题意:

模拟OJ的成绩排名。

输入:题数n、单位罚时m;之后每行数据代表一个学生的信息:用户名(不超过10个字符)、n道题的的得分现状。

每道题的得分现状:负数表示该学生在该题上有过的错误提交次数但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上了一对括号,里面有个正数b,则表示该学生AC了这道题,耗去了时间a,同时曾经错误提交了b次 。

每个同学的时间分=\sum(AC所耗的时间+错误提交×单位罚时)  对于没有AC的题目,不需要管它,错误提交也不计入时间分

输出排名:先按AC题数的多少排,多的在前,再按时间分的多少排,少的在前,如果凑巧前两者都相等,则按名字的字典序排,小的在前。

  • 做法:

结构体Student记录每个学生的用户名(name)、AC题数(cnt)、时间分(grade),重写比较方法,第一关键字cnt降序、第二关键字grade升序、第三关键字name升序。  vector<Student>保存所有学生。

字符串s循环读入得分现状,使用stoi将其转换成数字,若该数字<=0,不做处理;若该数字大于0,AC题数cnt++,然后遍历字符串s的每个字符直到找到"(",从下一个字符开始模拟读入,直到")",得到错误提交次数。该同学的时间分+=错误提交次数×单位罚时。构造该同学的Student添加进vector。   

使用sort函数对vector进行排序,cout<<setw(n)<<left/right<<......<<endl;控制输出格式。

  • 代码:
#include<cstdio>
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<iomanip>
using namespace std;
//学生结构体 
struct Student{
	string name;//用户名 
	int cnt;//AC题数 
	int grade;//时间分 
	//重写比较方法 
	bool operator<(const Student&p)const{
		if(cnt!=p.cnt) return cnt>p.cnt;//第一关键字 AC题数 降序 
		if(grade!=p.grade) return grade<p.grade;//第二关键字 时间分 升序 
		if(name!=p.name) return name<p.name;//第三关键字 用户名 升序 
	}
};
int main()
{
	int n,m;
	string name;
	string s;//每道题的得分现状 
	vector<Student> v;
	cin>>n>>m;
	while(cin>>name)
	{
		Student p;
		p.name=name;
		int grade=0;//时间分 
		int cnt=0;//AC题数 
		for(int i=0;i<n;i++)
		{
			cin>>s;//读入一个题的得分现状
			int temp=stoi(s);//转换为数字 
			if(temp<=0){}//小于0 不需处理 
			else
			{
				cnt++;//AC题数++ 
				grade+=temp;//AC所耗的时间 
				int k=0;
				while(s[k]!='('&&k<s.size()) k++; //略过(前面的字符 
				int y=0;//错误提交次数 
				k++;
				while(s[k]!=')'&&k<s.size())
				{//模拟读入 
					y=y*10+s[k]-'0';
					k++;
				}
				grade+=m*y;//罚时 
			}	
		}
		p.cnt=cnt;
		p.grade=grade; 
		v.push_back(p);//将该学生加入vector 
	}
	//排序 
	sort(v.begin(),v.end());
	for(int j=0;j<v.size();j++)
	{
		cout<<setw(10)<<left<<v[j].name<<" ";
		cout<<setw(2)<<right<<v[j].cnt<<" ";
		cout<<setw(4)<<right<<v[j].grade<<endl;
		
	}
	return 0;
}
  • 改进:

巧妙处理得分现状的读入:通过sscanf("s,%d(%d)",&a,&b)返回的读入的个数,区分不同的得分现状

改进部分的代码:

cin>>s;//读入一个题的得分现状
if(sscanf(s,"%d(%d)",&a,&b)==1){//s是一个char数组
    if(a>0){
        cnt++;
        grade+=a;
    } 
}else{
    cnt++;
    grade=grade+a+b*m;
}
  • 总结:

scanf格式读入可以方便的处理字符串 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值