当前位置: 代码迷 >> 综合 >> Week2 实验B 成绩排名
  详细解决方案

Week2 实验B 成绩排名

热度:13   发布时间:2024-01-27 04:49:43.0

题意:

模拟OJ的成绩排名。                                                                                                                                                                           输入:题数n、单位罚时m;之后每行数据代表一个学生的信息:用户名(不超过10个字符)、n道题的的得分现状。                             每道题的得分现状:负数表示该学生在该题上有过的错误提交次数但到现在还没有AC,正数表示AC所耗的时间,如果正数a跟上了一对括号,里面有个正数b,则表示该学生AC了这道题,耗去了时间a,同时曾经错误提交了b次                                                        每个同学的时间分=(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格式读入可以方便的处理字符串