题解:洛谷 AT_abc466_b Representative Balls

【题目来源】

洛谷:AT_abc466_b [ABC466B] Representative Balls

【题目描述】

There are \(N\) balls.

The color of the \(i\)-th ball is \(C_i\), and its size is \(S_i\). Here, the colors are represented by integers \(1, 2, \ldots, M\).

For \(k = 1, 2, \ldots, M\), output the maximum size of a ball of color \(k\), or -1 if there is no ball of color \(k\).

\(N\) 个球。

\(i\) 个球的颜色为 \(C_i\),大小为 \(S_i\)。这里,颜色用整数 \(1, 2, \ldots, M\) 表示。

对于 \(k = 1, 2, \ldots, M\),输出颜色为 \(k\) 的球的最大大小,如果不存在颜色为 \(k\) 的球,则输出 -1

【输入】

The input is given from Standard Input in the following format:

\(N\) \(M\)
\(C_1\) \(S_1\)
\(C_2\) \(S_2\)
\(\vdots\)
\(C_N\) \(S_N\)

【输出】

In the order \(k = 1, 2, \ldots, M\), output the maximum size of a ball of color \(k\) if such a ball exists, or -1 otherwise, separated by spaces.

【输入样例】

4 5
1 3
2 10
1 7
4 9

【输出样例】

7 10 -1 9 -1

【核心思想】

  1. 问题分析:给定 \(N\) 个球,每个球有颜色 \(C_i \in [1, M]\) 和大小 \(S_i\)。需要对每种颜色 \(k \in [1, M]\),输出该颜色球的最大大小,若该颜色不存在则输出 \(-1\)。这是一个桶统计 + 在线更新最大值问题,核心在于按颜色分组并维护每组的最大值。

  2. 算法选择

    • 桶数组维护最大值:用数组 \(maxS[k]\) 记录颜色 \(k\) 的最大大小,初始化为 \(-1\) 表示该颜色尚未出现
    • 线性扫描更新:遍历所有球,对每个球更新对应颜色的最大值
  3. 关键步骤

    • 初始化\(maxS[1..M] \leftarrow -1\)
    • 遍历所有球\(i\)\(1\)\(N\)):
      • 读入 \(C_i\)\(S_i\)
      • \(maxS[C_i] \leftarrow \max(maxS[C_i], S_i)\)
    • 按序输出\(k\)\(1\)\(M\)):输出 \(maxS[k]\)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N + M)\),遍历 \(N\) 个球更新最大值,再遍历 \(M\) 种颜色输出
    • 空间复杂度:\(O(M)\),桶数组 \(maxS\) 的大小
  5. 桶统计与在线更新的核心思想

    • 分组聚合:将 \(N\) 个元素按颜色分组,每组只需维护一个最大值,无需存储所有元素
    • 在线更新:读入每个球时立即更新对应颜色的最大值,无需先存储全部数据再处理,节省空间且只需单次遍历
    • 哨兵值设计:初始值设为 \(-1\) 兼具两种语义——表示该颜色尚未出现(不存在),同时满足"不存在时输出 \(-1\)"的要求
    • 顺序输出保证:按 \(k = 1\)\(M\) 的顺序输出,符合题目要求的输出格式
    • 适用于按类别分组求最值、类别编号范围已知且有限的统计类问题

【算法标签】

模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
const int N = 105;                 // 常量:最大球数量

int n, m;                          // n: 球的数量; m: 颜色种类数
int c[N];                          // c[i]: 第 i 个球的颜色
int s[N];                          // s[i]: 第 i 个球的大小
int maxS[N];                       // maxS[k]: 颜色为 k 的球的最大大小,初始化为 -1

int main()
{
    cin >> n >> m;                 // 读入球的数量和颜色种类数

    memset(maxS, -1, sizeof(maxS));  // 初始化所有颜色的最大大小为 -1(表示不存在)

    for (int i = 1; i <= n; i++)  // 读入每个球的信息
    {
        cin >> c[i] >> s[i];       // 读入第 i 个球的颜色和大小
        maxS[c[i]] = max(maxS[c[i]], s[i]);  // 更新该颜色对应的最大大小
    }

    for (int i = 1; i <= m; i++)  // 按颜色 1 到 M 的顺序输出
        cout << maxS[i] << " ";  // 输出颜色 i 的最大大小(不存在则为 -1)

    cout << endl;

    return 0;
}

【运行结果】

4 5
1 3
2 10
1 7
4 9
7 10 -1 9 -1
posted @ 2026-07-13 09:39  团爸讲算法  阅读(9)  评论(0)    收藏  举报