题目地址:PAT1080.MOOC期末成绩(25)
题目描述:
对于在中国大学MOOC(http://www.icourse163.org/)学习“数据结构”课程的学生,想要获得一张合格证书,必须首先获得不少于200分的在线编程作业分,然后总评获得不少于60分(满分100)。总评成绩的计算公式为 G = (G期中x 40% + G期末x 60%),如果 G期中 > G期末;否则总评 G 就是 G期末。这里 G期中 和 G期末 分别为学生的期中和期末成绩。
现在的问题是,每次考试都产生一张独立的成绩单。本题就请你编写程序,把不同的成绩单合为一张。
易错分析:
1. 数组一定要开的大,我这里是用了300100,光开10100是不够的。因为这题可能会出现9999个同学只做了编程题、9999个同学只做了期中考试、9999个同学只做了期末考试,只有1个同学3个项目都参加,这样就需要差不多30000大小的数组开销。
2. 需要判断学生的成绩合理性。
解题方法:
用1个结构体存储学生所需要的信息,然后用map建立学生学号与下标idx的下标,不但能够省空间还能省查找的时间,接下来就是按照题目的判断进行,将合格的同学放入vector,然后用sort函数排序输出即可。
程序:
#include <iostream>
#include <map>
#include <vector>
#include <cstdio>
#include <algorithm>
using namespace std;
struct Stu
{
string ID;
double CodingGrade = -1, MidGrade = -1, FinalGrade = -1, Grade = -1;
}Students[30100];
int cmp(Stu stu1, Stu stu2)
{ /* 如果成绩不相等,就按成绩降序排列,如果相等则按学号递增排列 */
return stu1.Grade != stu2.Grade ? stu1.Grade > stu2.Grade : stu1.ID < stu2.ID;
}
int main(int argc, char const *argv[])
{
string id;
map <string, int> S;
int Arr[3], grade, idx = 0; // Arr保存P,M,N人数
cin >> Arr[0] >> Arr[1] >> Arr[2];
for (int i = 0; i < 3; i++)
{ /* 将成绩输入 */
for (int j = 0; j < Arr[i]; j++)
{
cin >> id >> grade;
if (S[id] == 0) // 给每一个ID都建立一个下标
S[id] = ++idx;
int StuID = S[id]; // 保存该学号的下标
// cout << idx <<endl;
Students[StuID].ID = id;
if (i == 0) /* 如果输入的是编程成绩 */
Students[StuID].CodingGrade = grade;
else if (i == 1) /* 如果输入的是期中成绩 */
Students[StuID].MidGrade = grade;
else /* 如果输入的期末成绩 */
Students[StuID].FinalGrade = grade;
}
}
vector <Stu> v; // 保存合格的同学
for (int k = 1; k <= idx; k++) // 参加期末考试才有机会能通过
{
if(Students[k].CodingGrade >= 200 && Students[k].CodingGrade <= 900)
{
if (Students[k].MidGrade > Students[k].FinalGrade && Students[k].MidGrade <= 100 && Students[k].FinalGrade >= 0) // 四舍五入
Students[k].Grade = (int)(0.4*Students[k].MidGrade + 0.6*Students[k].FinalGrade + 0.5);
else if (Students[k].MidGrade <= Students[k].FinalGrade && Students[k].MidGrade >= -1 && Students[k].FinalGrade <= 100)
Students[k].Grade = Students[k].FinalGrade;
if (Students[k].Grade >= 60) // 如果及格
v.push_back(Students[k]);
}
}
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < v.size(); i++)
cout << v[i].ID << " " << v[i].CodingGrade << " " << v[i].MidGrade << " " << v[i].FinalGrade << " " << v[i].Grade << endl;
return 0;
}