1 条题解

  • 0
    @ 2026-6-19 10:30:26

    📝 题目大意

    给定 5N5N 个评委的打分,去掉最高的 NN 个分数和最低的 NN 个分数,求剩余 3N3N 个分数的平均值。

    💡 解题思路

    1. 题目分析NN 最大为 100100,因此 5N5N 最多只有 500500 个数据。XiX_i 范围 [0,100][0, 100],数据量很小,直接排序后截取中间部分求和即可。
    2. 算法推导
      • 将所有 5N5N 个分数存入数组 a,然后从小到大排序。
      • 去掉最小的 NN 个元素(索引 0N10 \sim N-1)和最大的 NN 个元素(索引 4N5N14N \sim 5N-1)。
      • 对中间 3N3N 个元素(索引 N4N1N \sim 4N-1)求和,记为 sum
      • 最终答案 = sum / (3 * N)
    3. 边界与细节
      • 输出要求误差不超过 10510^{-5},使用 double 类型并保留足够小数位(如 1212 位)即可。
      • N=1N=1 时,去掉 11 个最高和 11 个最低,剩余 33 个取平均。
      • 若存在多个相同的最高/最低分,去掉其中任意 NN 个不影响结果,因为剩下的 3N3N 个元素集合是确定的。

    ⏱️ 复杂度分析

    • 时间复杂度O(NlogN)O(N \log N),其中 5N5N 个元素排序。
    • 空间复杂度O(N)O(N),存储 5N5N 个分数。

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
      int n;
      cin >> n;
      double sum = 0.0;
      vector<double> a(5 * n);          // 存储 5N 个分数
      for (int i = 0; i < 5 * n; i++) {
        cin >> a[i];
      }
      sort(a.begin(), a.end());         // 从小到大排序
      // 跳过最小的 N 个和最大的 N 个,取中间 3N 个求和
      for (int i = n; i < 4 * n; i++) {
        sum += a[i];
      }
      // 输出平均值,保留足够精度
      cout << fixed << setprecision(12) << double(sum / (3 * n)) << '\n';
    }
    
    • 1

    信息

    ID
    683
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者