详细介绍:2024CSP-S提高组第二轮试题及解析(第一题、决斗(duel))

一、先看原题:

二、形象化理解题目:

有一天,小 Q 得到了一堆“怪兽卡牌”,每张卡牌上写着一个数字,比如:

1 2 3 1 2

每个数字代表这只怪兽的“实力”(攻击力=防御力)。

游戏规则是:

一只怪兽如果攻击另一只怪兽,只有当自己的数字 > 对方的数字时,才能把对方打退场。

数字小的打不动数字大的。

数字一样的,也打不动。


三、我们的重要发现:

第一件重要的事:同样数字的怪兽打不动彼此!

比如两只“2”的怪兽:

2 攻击 2 -> 失败(2不能大于2)

所以:

数字一样的怪兽无论怎么攻击,都不会减少数量!

它们会一起“活到最后”。


第二件重要的事:数字相同的怪兽越多,越难消灭

比如有 5 只怪兽:

2 2 2 1 3

其中“2”有 3 只。

那这 3 只“2”是无法互相消灭的,
而且数字比 2 小的“1”不能打它们,
只有“3”能攻击它们。

但只有 1 只“3”,它最多只能打一只。

最后,“2”们还是会剩下几只。

所以:

最终剩下的怪兽数量,最少也要 ≥ 最多的那个数字出现了几次。

因为这些怪兽互相消灭不了。

我们叫这个为:

众数的数量(出现次数最多的数字的数量)


第三个重要的事:真的能做到只剩下“众数的怪兽”吗?

答案:可以!

具体策略:

  1. 让“大的怪兽”去吃掉比自己小的怪兽

  2. “更大的怪兽”再去吃掉“刚刚那个怪兽”

  3. 一直这样“吃来吃去”

所以最终一定可以做到:

最后剩下的怪兽数量  =  出现次数最多的数字的数量。


四、这是不是贪心算法呢?

1、 这是“隐含地使用了贪心思想”,但不需要写贪心过程

因为我们不用真的模拟每一次攻击,而是直接通过数学分析知道最优策略。

就像有时候:

  • 不需要真的走楼梯

  • 只要算出步数

  • 就能知道最快时间

这里也是一样:

我们通过贪心策略确定“最少能剩多少只怪兽”后,发现这个值就是数字出现最多的次数。


2、那它的“贪心原则”到底是什么?

这道题里的贪心原则非常清晰:

贪心原则:永远让“大怪兽”去吃“小怪兽”。

能吃就吃最弱的,永远先把最容易消灭的怪兽吃掉。

这是从“游戏中每个怪兽只能攻击一次”的规则出发。

因为:

  • 大怪兽能吃掉小怪兽

  • 小怪兽不能吃掉大怪兽

  • 同数字怪兽互相吃不掉

  • 大怪兽太宝贵,不能浪费在不该吃的人身上

  • 所以必须把每一次攻击都用在“最弱的怪兽”身上

这就是典型贪心思想:

每一步都做“当前最有利”的选择:
去减少最弱的怪兽。


3、贪心能做到什么?

 贪心能保证:

所有“非众数”的怪兽,都可以通过一连串“大吃小”被全部消灭。

这就是为什么我们最终能做到:

最后只剩下出现最多那一类怪兽(众数)。

贪心策略给出了一个可行方案。


4、“贪心结果”为何就是众数?

因为同一个数字的怪兽互相无法攻击,所以它们永远消灭不完。

比如:

2, 2, 2

这三只永远不会互相吃,怎么贪心都不能减少它们的数量。

所以:

贪心能吃掉所有非众数怪兽

而观念上“吃不掉的怪兽数量”刚好就是“众数的数量”

这件事 不需要模拟,直接根据数学推导即可得出最优解。

于是:

⭐贪心思想决定了“最多能吃掉多少”

⭐数学逻辑决定了“最少会剩下多少(众数)”


五、参考程序:

#include 
using namespace std;
int main() {
    freopen("duel.in", "r", stdin);
    freopen("duel.out", "w", stdout);
    int n;
    cin >> n;
    // 存每个数字出现了几次
    unordered_map cnt;
    int x;
    int maxCount = 0;
    for (int i = 0; i < n; i++) {
        cin >> x;
        cnt[x]++;              // x 这个数字又出现了一次
        maxCount = max(maxCount, cnt[x]); // 更新最多次数
    }
    // 输出出现最多数字的次数
    cout << maxCount << endl;
    return 0;
}

六、总结:

想要让最后留下来的怪兽越少越好?
那只需要想一件事情:
哪些怪兽“不能互相消灭”?

答案就是数字相同的怪兽。

所以:

那些数字最多的怪兽,一定无法被打完。

因此输出:

出现次数最多的数字的个数

posted @ 2025-12-19 08:50  gccbuaa  阅读(2)  评论(0)    收藏  举报