题解:洛谷 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
【核心思想】
-
问题分析:给定 \(N\) 个球,每个球有颜色 \(C_i \in [1, M]\) 和大小 \(S_i\)。需要对每种颜色 \(k \in [1, M]\),输出该颜色球的最大大小,若该颜色不存在则输出 \(-1\)。这是一个桶统计 + 在线更新最大值问题,核心在于按颜色分组并维护每组的最大值。
-
算法选择:
- 桶数组维护最大值:用数组 \(maxS[k]\) 记录颜色 \(k\) 的最大大小,初始化为 \(-1\) 表示该颜色尚未出现
- 线性扫描更新:遍历所有球,对每个球更新对应颜色的最大值
-
关键步骤:
- 初始化:\(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]\)
-
时间/空间复杂度:
- 时间复杂度:\(O(N + M)\),遍历 \(N\) 个球更新最大值,再遍历 \(M\) 种颜色输出
- 空间复杂度:\(O(M)\),桶数组 \(maxS\) 的大小
-
桶统计与在线更新的核心思想:
- 分组聚合:将 \(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
浙公网安备 33010602011771号