1 条题解
-
0
核心思路
这个问题有一个著名的优化解法,可以同时找出最大值和最小值,比较次数约为 ( \lceil 3N/2 \rceil - 2 )。
1. 基本思想
- 如果分别找最大值和最小值,各需要 (N-1) 次比较,总共 (2N-2) 次比较。
- 但我们可以成对处理元素,在每一对内部先比较一次,然后让胜者参与最大值的竞争,败者参与最小值的竞争,从而减少比较次数。
2. 算法步骤
-
初始化
如果 (N) 是奇数,将第一个元素同时设为当前最大值和最小值。
如果 (N) 是偶数,先比较前两个元素,确定初始的最大值和最小值。 -
成对处理
将剩下的元素两两分组。对每一对 ((a, b)):- 先比较 (a) 和 (b)(1 次比较)
- 用胜者(较大者)与当前最大值比较(1 次比较)
- 用败者(较小者)与当前最小值比较(1 次比较)
这样每 2 个元素用了 3 次比较,平均每个元素 1.5 次比较。
-
特殊情况
如果 (N) 是奇数,第一个元素没有配对,已经作为初始最大最小值,剩下的 (N-1) 个元素(偶数个)进行成对处理。
3. 比较次数分析
-
(N) 为偶数:
初始比较 1 次(确定第一对的最大最小值),剩下 (\frac{N}{2} - 1) 对,每对 3 次比较。
总次数 = (1 + 3 \times (\frac{N}{2} - 1) = \frac{3N}{2} - 2)。 -
(N) 为奇数:
初始最大最小值设为第一个元素(0 次比较),剩下 (N-1) 个元素(偶数个)分成 (\frac{N-1}{2}) 对,每对 3 次比较。
总次数 = (3 \times \frac{N-1}{2} = \lceil \frac{3N}{2} \rceil - 2)。
当 (N = 400) 时,比较次数 = (3 \times 400 / 2 - 2 = 598) 次,满足 600 次的限制。
4. 实现要点
- 在
Ramen函数中,按照上述分组策略调用Compare。 - 维护两个变量
min_index和max_index记录当前找到的最小和最大元素的下标。 - 最后调用
Answer(min_index, max_index)结束。
这种方法在比较次数上是最优的(理论下界就是 ( \lceil 3N/2 \rceil - 2 )),并且完全适合本题的数据范围 (N \leq 400) 和限制 600 次比较。
- 1
信息
- ID
- 4393
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者