对于在中国大学MOOC(http://www.icourse163.org/ )学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分(满分100)。总评成绩的计算公式为 G=(Gmid−term×40%+Gfinal×60%),如果 Gmid−term>Gfinal;否则总评 G 就是 Gfinal。这里 Gmid−term和 Gfinal分别为学生的期中和期末成绩。
现在的问题是,每次考试都产生一张独立的成绩单。本题就请你编写程序,把不同的成绩单合为一张。
输入在第一行给出3个整数,分别是 P(做了在线编程作业的学生数)、M(参加了期中考试的学生数)、N(参加了期末考试的学生数)。每个数都不超过10000。
接下来有三块输入。第一块包含 P 个在线编程成绩 Gp;第二块包含 M 个期中考试成绩 Gmid−term;第三块包含 N 个期末考试成绩 Gfinal。每个成绩占一行,格式为:学生学号 分数。其中学生学号为不超过20个字符的英文字母和数字;分数是非负整数(编程总分最高为900分,期中和期末的最高分为100分)。
打印出获得合格证书的学生名单。每个学生占一行,格式为:
学生学号 G p G mid−term G final G
如果有的成绩不存在(例如某人没参加期中考试),则在相应的位置输出“−1”。输出顺序为按照总评分数(四舍五入精确到整数)递减。若有并列,则按学号递增。题目保证学号没有重复,且至少存在1个合格的学生。
思路:我们要处理的问题大致如下: 1、题中输入时姓名是随便输入的,想输入谁的就输入谁的 2、输入的姓名可能只存在一块有 3、要将单个人的信息放在一个结构体里 4、对其结构体进行题中要求排序 5、按要求输出 对于乱序输入的问题,我们可以用一个map捆绑学生姓名及其在结构体数组的下标,再用一个hash表判断这个学生姓名是否出现过,具体操作如下:
#include <iostream> #include <algorithm> #include <string> #include <map> using namespace std; struct student{ string name; int gp,gmid,gend,g; student(){ gp=gmid=gend=g=-1; }; }s[100000]; bool cmp(student a,student b){ if(a.g==b.g) return a.name<b.name; return a.g>b.g; } int main() { int p,m,n,cnt=0,gp,gm,gf; string name; map<string,int> mp,hash; cin >>p>>m>>n; for(int i=0;i<p;i++){ cin >>name>>gp; s[cnt].name=name; s[cnt].gp=gp; mp[name]=cnt++; hash[name]=1; } for(int i=0;i<m;i++){ cin >>name>>gm; if(hash[name]) s[mp[name]].gmid=gm; else{ s[cnt].name=name; s[cnt].gmid=gm; mp[name]=cnt++; hash[name]=1; } } for(int i=0;i<n;i++){ cin >>name>>gf; if(hash[name]) s[mp[name]].gend=gf; else{ s[cnt].name=name; s[cnt].gend=gf; mp[name]=cnt++; hash[name]=1; } } for(int i=0;i<cnt;i++){ if(s[i].gmid>s[i].gend) s[i].g=(s[i].gmid*0.4+s[i].gend*0.6+0.5); else s[i].g=s[i].gend; } sort(s,s+cnt,cmp); for(int i=0;i<cnt;i++) if(s[i].g>=60&&s[i].gp>=200) printf("%s %d %d %d %d\n",s[i].name.c_str(),s[i].gp,s[i].gmid,s[i].gend,s[i].g); return 0; }接下来我们对其进行优化,首先我们可以发现,在输入编程成绩时,对于小于200的学生其实没必要进行处理了,而且我们可以把需要进行处理的单个结构体放入一个vector中,而在输入期中成绩时,我们只需要对vector里的元素进行处理,输入期末成绩也是一样的,完了之后用sort将其排序并且输出大于60分的学生信息即可,优化后代码行数减少了10多行:
#include <iostream> #include <algorithm> #include <string> #include <map> #include <vector> using namespace std; struct student{ string name; int gp,gmid,gend,g; student(){ gp=gmid=gend=g=-1; }; }s; bool cmp(student a,student b){ if(a.g==b.g) return a.name<b.name; return a.g>b.g; } int main() { int p,m,n,cnt=1,score; //cnt一定要等于1 string name; vector<student> v; map<string,int> mp; cin >>p>>m>>n; for(int i=0;i<p;i++){ cin >>s.name>>s.gp; if(s.gp>=200){ //把有必要处理的元素放入v中 v.push_back(s); mp[s.name]=cnt++; } } for(int i=0;i<m;i++){ cin >>s.name>>s.gmid; if(mp[s.name]!=0) v[mp[s.name]-1].gmid=s.gmid; } for(int i=0;i<n;i++){ //在该过程中直接计算总成绩 cin >>s.name>>s.gend; if(mp[s.name]!=0){ v[mp[s.name]-1].gend=s.gend; v[mp[s.name]-1].g=v[mp[s.name]-1].gend; if(v[mp[s.name]-1].gmid>v[mp[s.name]-1].gend) v[mp[s.name]-1].g=(v[mp[s.name]-1].gmid*0.4+v[mp[s.name]-1].gend*0.6+0.5); } } sort(v.begin(),v.end(),cmp); //排序 for(int i=0;i<v.size();i++) //输出 if(v[i].g>=60) printf("%s %d %d %d %d\n",v[i].name.c_str(),v[i].gp,v[i].gmid,v[i].gend,v[i].g); return 0; }