【天梯赛L1-7】天梯赛的善良 - 最小/最大能力值统计

一、题目描述

天梯赛命题组需要统计所有参赛学生的最小能力值最大能力值,并统计具有这两个能力值的学生人数。
输入格式

  • 第一行:学生总数 N(≤ 2×10⁴)

  • 第二行:N 个不超过 10⁶ 的正整数(能力值)

输出格式

  • 第一行:最小能力值 + 该能力值人数

  • 第二行:最大能力值 + 该能力值人数

示例输入

复制

10
86 75 233 888 666 75 886 888 75 666

示例输出

复制

75 3
888 2

二、题目分析
  1. 核心需求

    • 找到数组中的最小值最大值

    • 统计这两个值的出现次数

  2. 关键点

    • 数据范围较大(N ≤ 2×10⁴),需用O(n)或O(nlogn)算法。

    • 最小值/最大值可能有重复值,需正确计数。

    • 暴力法(命题组看了会沉默):

      • 直接遍历数组,记录最小值和最大值,再数一遍有几个。

      • 时间复杂度:O(n)(但写起来有点啰嗦)。

    • 排序法(我选择偷懒):

      • 先排序,最小值在开头,最大值在结尾。

      • 然后数数开头有多少个一样的,结尾有多少个一样的。

      • 时间复杂度:O(nlogn)(但代码短,适合我这种懒人)。

    • 我选排序法!(因为STL的 sort 太好用了)


三、代码实现

#include<bits/stdc++.h>
using namespace std;
int main() {
    int a;
    cin >> a;
    int C[20005];
    for (int i = 1; i <= a; i++) {
        cin >> C[i];
    }
    sort(C + 1, C + 1 + a);  // 升序排序
    int numa = 1, numb = 1;   // 初始化最小/最大值的计数
    // 统计最小值出现次数
    for (int i = 1; i <= a; i++) {
        if (C[i] == C[i + 1]) numa++;
        else break;
    }
    // 统计最大值出现次数
    for (int i = a; i >= 0; i--) {
        if (C[i] == C[i - 1]) numb++;
        else break;
    }
    // 输出结果
    cout << C[1] << " " << numa << endl;
    cout << C[a] << " " << numb << endl;
    return 0;
}

四、代码解析
  1. 输入处理

    • 用数组 C 存储所有学生的能力值,下标从1开始(符合题目习惯)。

  2. 排序优化

    • 调用 sort(C+1, C+1+a) 对能力值升序排序,使得最小值为 C[1],最大值为 C[a]

  3. 统计最小值次数

    • 从前往后遍历,若当前值等于下一个值(C[i] == C[i+1]),则计数 numa++,否则退出循环。

  4. 统计最大值次数

    • 从后往前遍历,若当前值等于前一个值(C[i] == C[i-1]),则计数 numb++,否则退出循环。

  5. 输出结果

    • 直接取 C[1] 和 C[a] 作为最小/最大值,并输出对应的计数。


五、总结

本题通过排序+双指针计数巧妙解决了最小/最大值统计问题,适合初学者练习数组操作和边界处理。命题组的“善良”在于数据范围友好,允许使用排序解法。

关键点:排序后的首尾元素即是最值,重复值需正确计数!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值