P16631 [GKS 2017 #F] Kicksort

题目描述

在 Kickstart,我们是著名的快速排序算法的爱好者,该算法从列表中选择一个基准值,根据其他值与基准值的比较结果将其移动到两个新列表之一,然后递归地对每个新列表进行排序。然而,算法可能会选择一个基准值,导致所有其他值最终都只进入两个新列表中的一个,这违背了分治策略的初衷。我们称这样的基准值为**最坏情况基准**。 为了尝试避免这个问题,我们创建了自己的变体 Kicksort。有人告诉我们,使用中间的值作为基准值效果很好,因此我们的算法如下: ``` Kicksort(A): // A 是一个有 E 个元素的 0 索引列表 如果 E ≤ 1,则返回 A。 否则: 创建空的新列表 B 和 C。 选择 A[floor((E-1)/2)] 作为基准值 P。 对于 i = 0 到 E-1,除了 i = floor((E-1)/2): 如果 A[i] ≤ P,则将其追加到 B。 否则,将其追加到 C。 返回列表 Kicksort(B) + [P] + Kicksort(C)。 // [P] 是仅包含 P 的新列表;+ 表示连接 ``` 为了练习,我们尝试在 $1$ 到 $N$ 的排列列表上运行 Kicksort。不幸的是,看起来 Kicksort 仍然存在与快速排序相同的问题:有可能每个基准值都是**最坏情况基准**! 例如,考虑列表 `1 4 3 2`。Kicksort 会选择 $4$ 作为基准值,所有其他值 `1 3 2` 都将进入两个新列表中的一个。然后,当在列表 `1 3 2` 上调用 Kicksort 时,它会选择 $3$,再次所有其他值都将进入两个新列表中的一个。最后,它会从列表 `1 2` 中选择 $1$,另一个值 $2$ 当然也只会进入两个新列表中的一个。在每种情况下,算法都会选择一个**最坏情况基准**。(注意,当对包含 $0$ 或 $1$ 个元素的列表调用 Kicksort 时,它根本不会选择基准值。) 请帮助我们进一步研究!给定一个 $1$ 到 $N$ 的排列,判断 Kicksort 是否只会选择**最坏情况基准**。

输入格式

输入的第一行给出测试用例的数量 $T$。接下来有 $T$ 个测试用例;每个测试用例由两行组成。第一行包含一个整数 $N$:排列中元素的数量。第二行包含 $N$ 个整数 $A_i$,它们是 $1$ 到 $N$ 的一个排列。

输出格式

对于每个测试用例,输出一行,格式为 `Case #x: y`,其中 $x$ 是测试用例编号(从 $1$ 开始),$y$ 为 `YES`(如果 Kicksort 在对该列表排序时只会选择最坏情况基准)或 `NO`(否则)。

说明/提示

样例 #1 就是题目描述中给出的例子。 在样例 #2 中,我们的第一个基准值是 $1$,这是一个最坏情况基准,因为它使所有其他值 $2$、$3$、$4$ 都进入两个新列表中的一个。然而,在列表 $2$、$3$、$4$ 上调用 Kicksort 时,它会选择 $3$ 作为基准值。这不是一个最坏情况基准,因为它将 $2$ 放入一个新列表,将 $4$ 放入另一个。 在样例 #3 中,Kicksort 首先选择最坏情况基准 $2$,之后没有其他基准需要选择。 在样例 #4 中,Kicksort 首先选择 $2$,这不是一个最坏情况基准。 ### 限制条件 $A_i$ 是 $1$ 到 $N$ 的一个排列。 **小数据集(测试集 1 – 可见)** $1 \le T \le 32$。 $2 \le N \le 4$。 **大数据集(测试集 2 – 隐藏)** $1 \le T \le 100$。 $2 \le N \le 10000$。 翻译由 DeepSeek V4 Pro 完成