题解:洛谷 AT_abc470_b Monocolor

【题目来源】

洛谷:AT_abc470_b [ABC470B] Monocolor

【题目描述】

\(N\) 个球。每个球都涂有 \(N\) 种颜色:颜色 \(1\) 到颜色 \(N\) 。第 \(i\) 个球第 \((1\le i\le N)\) 个球的颜色是 \(C_ i\)

只需一次操作,就可以将任意一个球的颜色更改为 \(N\) 中的任意一种颜色。

求使所有球的颜色相同所需的最少操作次数。

【输入】

输入内容由标准输入法提供,格式如下

\(N\)

\(C_1\) \(C_2\) \(\ldots\) \(C_N\)

【输出】

输出答案

【输入样例】

4
3 1 2 1

【输出样例】

2

【核心思想】

  1. 问题分析:给定 \(N\) 个球,每个球有颜色 \(C_i \in [1, N]\),每次操作可将任意一球改为任意颜色。求使所有球颜色相同的最少操作次数。这是一个贪心/模拟问题,核心观察是:最优策略是将所有球改为出现次数最多的颜色,这样需要改变的球数最少。

  2. 算法选择

    • 哈希表统计频率:用 map 统计每种颜色出现的次数
    • 贪心取最大频率:答案 = \(N - \max(\text{频率})\),即保留出现最多的颜色,其余全部修改
  3. 关键步骤

    • 统计频率:遍历 \(C_1\)\(C_N\),用 mp[x]++ 记录颜色 \(x\) 的出现次数
    • 找最大频率:遍历 mp,找到出现次数最多的颜色次数 \(maxn\)
    • 计算答案\(n - maxn\)(将非最大频率颜色的球全部改为该颜色)
  4. 时间/空间复杂度

    • 时间复杂度:\(O(N)\),遍历统计 + 遍历找最大值
    • 空间复杂度:\(O(N)\),哈希表存储颜色频率
  5. 贪心策略的核心思想

    • 频率最大化原理:将所有球统一为某一种颜色时,选择出现次数最多的颜色作为目标色,需要修改的次数最少
    • 操作等价性:每次操作只能改一个球的颜色,与改为什么颜色无关,因此只需最小化修改次数
    • 鸽巢原理保证\(N\) 个球 \(N\) 种颜色,必有至少一种颜色出现,但不一定有颜色重复
    • 适用于众数问题、最小修改次数、颜色统一类问题

【算法标签】

入门 #模拟

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int n, maxn=-1e9; // n:球的总数, maxn:出现次数最多的颜色的数量
map<int, int> mp; // mp[x]:颜色x出现的次数

int main()
{
    cin >> n; // 读入球的总数
    for (int i=1; i<=n; i++) // 循环读入每个球的颜色
    {
        int x; cin >> x; // 读入第i个球的颜色
        mp[x]++; // 该颜色出现次数加1
    }
    // 遍历所有颜色,找出出现次数最多的颜色
    for (auto t : mp)
        maxn = max(maxn, t.second); // 更新最大出现次数
    // 最少操作次数 = 总球数 - 出现次数最多的颜色的数量
    // 即将其他所有球都改为该颜色
    cout << n - maxn << endl;
    return 0;
}

【运行结果】

4
3 1 2 1
2
posted @ 2026-08-23 21:53  团爸讲算法  阅读(4)  评论(0)    收藏  举报