{ }codelper
平均值P0225

班级平均分与年级平均分

一个年级有 m 个班。
第一行给出 m。
接下来 m 行,每行给出一个班的学生人数 k 和 k 名学生的分数,用空格分开。
按输入顺序,每个班在单独一行输出该班的平均分。
最后一行输出年级平均分。
年级平均分是年级所有学生的分数之和除以年级学生总人数。
所有平均分都在小数第三位四舍五入,写成小数点后恰好两位(85 → 85.00)。
为了不在四舍五入上产生歧义,所有要输出的平均分乘以 100 后的小数部分都不大于 0.4 或不小于 0.6。

输入
1 ≤ m ≤ 100,1 ≤ k ≤ 100,0 ≤ 分数 ≤ 100(整数)
输出
m 行班级平均分,最后一行年级平均分(都保留两位小数)
样例 1 · stdin
2
3 90 80 70
1 100
stdout
80.00
100.00
85.00
样例 2 · stdin
2
3 0 0 1
2 100 100
stdout
0.33
100.00
40.20
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

最大的陷阱是平均数的平均。
把各班平均分相加再除以班数,在各班人数不同时会和年级平均分不一样。
3 人、平均 80 的班和 1 人、平均 100 的班再求平均是 90,但 4 名学生的平均分是 340 ÷ 4 = 85。
所以要分别累计每个班的分数和与学生人数,最后再相除。
每个班的和都要从 0 重新开始。
第二个陷阱是整数除法。
C、C++、Java、C# 中 s / k 是两个 int 相除,只留下商。
要像 (double)s / k(C++ 写 static_cast<double>(s) / k)那样先转换再除。
double avg = s / k; 或 (double)(s / k) 时小数已经被舍掉了。
Python 3、JS、TS、Craykon 的 / 总会保留小数。
两位小数用 Python f"{x:.2f}"、JS/TS x.toFixed(2)、C printf("%.2f")、Java String.format(Locale.ROOT, "%.2f", x)、C# x.ToString("F2", CultureInfo.InvariantCulture)、Craykon 字符.保留小数(x, 2)。
C++ 一定要同时写 std::fixed。
只写 std::setprecision(2) 表示两位有效数字而不是两位小数,33.33 会输出成 33。
学生人数和分数在同一行,所以用 Python k, *scores = map(int, line.split()) 或 JS/TS const [k, ...scores] = … 分开读取会很方便。

Pythonmain.py · 11 行
m = int(input())out = []total = count = 0for _ in range(m):    k, *scores = map(int, input().split())    s = sum(scores)    out.append(f"{s / k:.2f}")    total += s          # 학년 평균은 반 평균이 아니라 점수 합과 학생 수를 모아서 구한다    count += kout.append(f"{total / count:.2f}")print("\n".join(out))
JavaScriptmain.js · 15 行
const lines = require("fs").readFileSync(0, "utf8").split("\n");const m = Number(lines[0]);const out = [];let total = 0;let count = 0;for (let i = 1; i <= m; i++) {  const [k, ...scores] = lines[i].trim().split(/\s+/).map(Number);  let s = 0;  for (const x of scores) s += x;  out.push((s / k).toFixed(2));  total += s; // 학년 평균은 점수 합과 학생 수를 모아서 구한다  count += k;}out.push((total / count).toFixed(2));console.log(out.join("\n"));
TypeScriptmain.ts · 16 行
import { readFileSync } from "node:fs";const lines: string[] = readFileSync(0, "utf8").split("\n");const m: number = Number(lines[0]);const out: string[] = [];let total = 0;let count = 0;for (let i = 1; i <= m; i++) {  const [k, ...scores]: number[] = lines[i].trim().split(/\s+/).map(Number);  let s = 0;  for (const x of scores) s += x;  out.push((s / k).toFixed(2));  total += s; // 학년 평균은 점수 합과 학생 수를 모아서 구한다  count += k;}out.push((total / count).toFixed(2));console.log(out.join("\n"));
JavaMain.java · 26 行
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.Locale;import java.util.StringTokenizer; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));        int m = Integer.parseInt(in.readLine().trim());        StringBuilder out = new StringBuilder();        int total = 0, count = 0;        for (int i = 0; i < m; i++) {            StringTokenizer st = new StringTokenizer(in.readLine());            int k = Integer.parseInt(st.nextToken());            int s = 0;            for (int j = 0; j < k; j++) s += Integer.parseInt(st.nextToken());            // int끼리 나누면 몫만 남으니 한쪽을 double로            out.append(String.format(Locale.ROOT, "%.2f", (double) s / k)).append('\n');            total += s;            count += k;        }        out.append(String.format(Locale.ROOT, "%.2f", (double) total / count)).append('\n');        System.out.print(out);    }}
C#Main.cs · 26 行
using System;using System.Globalization;using System.Linq;using System.Text; class Program{    static void Main()    {        int m = int.Parse(Console.ReadLine());        var sb = new StringBuilder();        int total = 0, count = 0;        for (int i = 0; i < m; i++)        {            int[] p = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();            int k = p[0];            int s = p.Skip(1).Sum();            // int끼리 나누면 몫만 남으니 한쪽을 double로            sb.Append(((double)s / k).ToString("F2", CultureInfo.InvariantCulture)).Append('\n');            total += s;            count += k;        }        sb.Append(((double)total / count).ToString("F2", CultureInfo.InvariantCulture)).Append('\n');        Console.Write(sb);    }}
C++main.cpp · 24 行
#include <iomanip>#include <iostream> int main() {    std::ios::sync_with_stdio(false);    int m;    std::cin >> m;    int total = 0, count = 0;    std::cout << std::fixed << std::setprecision(2);    for (int i = 0; i < m; i++) {        int k;        std::cin >> k;        int s = 0;        for (int j = 0; j < k; j++) {            int x;            std::cin >> x;            s += x;        }        std::cout << static_cast<double>(s) / k << "\n";        total += s;        count += k;    }    std::cout << static_cast<double>(total) / count << "\n";}
Cmain.c · 20 行
#include <stdio.h> int main(void) {    int m, k, x;    int total = 0, count = 0;    scanf("%d", &m);    for (int i = 0; i < m; i++) {        scanf("%d", &k);        int s = 0;        for (int j = 0; j < k; j++) {            scanf("%d", &x);            s += x;        }        printf("%.2f\n", (double)s / k); /* (double)로 바꾼 뒤에 나눈다 */        total += s;        count += k;    }    printf("%.2f\n", (double)total / count);    return 0;}
Craykonmain.cray · 17 行
m = 控制台.读行().转数字();total = 0;count = 0;循环 (i = 0; i < m; i++){    p = 控制台.读数字();    k = p[0];    s = 0;    循环 (j = 1; j <= k; j++)    {        s += p[j];    }    控制台.输出(字符.保留小数(s / k, 2));    total += s; // 학년 평균은 점수 합과 학생 수를 모아서 구한다    count += k;}控制台.输出(字符.保留小数(total / count, 2));