成绩计算

题目描述

每个同学在本学期修读了3门课程,分别取得了一个成绩,现在需要计算他们本学期的综合成绩。

首先进行成绩调整:成绩小于60分的课程按0分计算,其他课程不变;本学期的综合成绩即为所有调整成绩按照学分的加权平均值(四舍五入为整数)。

关于输入

输入共n+2行。

第一行,一个整数n,表示总共有n个学生。

第二行,三个整数x,y,z,表示三门课程的学分。

接下来第i+1到第n+2行,每行3个整数,表明第i个学生的3门课程的成绩ai1,ai2,ai3

关于输出

输出共n行。

每行7个整数,第i行为第i个学生三门课程调整前、调整后的成绩,以及其本学期的综合成绩。

核心技巧

  • lambda 表达式的使用:需要捕获xyz三个变量,同时需要按引用传递三个需要修改的成绩。同时通过在 lambda 表达式内部定义新的表达式,避免了成绩判断的代码冗余。
  • 类型转换:int 类型的除法运算结果仍然是 int 类型,需要转换为 floatdouble 类型进行运算,否则会丢失精度,得到错误结果。这里还有运算顺序的问题,在运算后将结果转换为浮点数是无效的,需要在运算前将其中一个操作数转换为浮点数。
  • 四舍五入:将浮点数转换为整数时,会采取向零取整的方式。在本题条件下,将浮点数加上 0.5 后再取整,可以实现四舍五入的效果。

参考答案

#include <iostream>
using std::cin, std::cout, std::endl;
int main(){
    int n, x, y, z;
    cin >> n;
    cin >> x >> y >> z;
    int* a = new int[n];
    int* b = new int[n];
    int* c = new int[n];
    for(int i = 0; i < n; i++){
        cin >> a[i] >> b[i] >> c[i];
    }
    auto f = [=](int &i, int &j, int &k) -> int {
        auto judge = [](int& x) { x = x < 60 ? 0 : x;};
        judge(i);
        judge(j);
        judge(k);
        return (double)(i*x + j*y + k*z) / (x + y + z) + 0.5;
    }
    ;
    for (int i = 0; i < n; i++) {
        cout << a[i] << " " << b[i] << " " << c[i] << " ";
        int tot = f(a[i], b[i], c[i]);
        cout << a[i] << " " << b[i] << " " << c[i] << " " << tot << endl;
    }
    delete[] a;
    delete[] b;
    delete[] c;
}