PAT乙 1080. MOOC期终成绩 (25)

题目地址: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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值