#P16631. [GKS 2017 #F] Kicksort

[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 的新列表;+ 表示连接

为了练习,我们尝试在 11NN 的排列列表上运行 Kicksort。不幸的是,看起来 Kicksort 仍然存在与快速排序相同的问题:有可能每个基准值都是最坏情况基准

例如,考虑列表 1 4 3 2。Kicksort 会选择 44 作为基准值,所有其他值 1 3 2 都将进入两个新列表中的一个。然后,当在列表 1 3 2 上调用 Kicksort 时,它会选择 33,再次所有其他值都将进入两个新列表中的一个。最后,它会从列表 1 2 中选择 11,另一个值 22 当然也只会进入两个新列表中的一个。在每种情况下,算法都会选择一个最坏情况基准。(注意,当对包含 0011 个元素的列表调用 Kicksort 时,它根本不会选择基准值。)

请帮助我们进一步研究!给定一个 11NN 的排列,判断 Kicksort 是否只会选择最坏情况基准

输入格式

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

输出格式

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

4
4
1 4 3 2
4
2 1 3 4
2
2 1
3
1 2 3
Case #1: YES
Case #2: NO
Case #3: YES
Case #4: NO

提示

样例 #1 就是题目描述中给出的例子。

在样例 #2 中,我们的第一个基准值是 11,这是一个最坏情况基准,因为它使所有其他值 223344 都进入两个新列表中的一个。然而,在列表 223344 上调用 Kicksort 时,它会选择 33 作为基准值。这不是一个最坏情况基准,因为它将 22 放入一个新列表,将 44 放入另一个。

在样例 #3 中,Kicksort 首先选择最坏情况基准 22,之后没有其他基准需要选择。

在样例 #4 中,Kicksort 首先选择 22,这不是一个最坏情况基准。

限制条件

AiA_i11NN 的一个排列。

小数据集(测试集 1 – 可见)

1T321 \le T \le 32

2N42 \le N \le 4

大数据集(测试集 2 – 隐藏)

1T1001 \le T \le 100

2N100002 \le N \le 10000

翻译由 DeepSeek V4 Pro 完成