取消合并清单


14

介绍

你们中的大多数人都熟悉用于对数字列表进行排序的合并排序算法。作为该算法的一部分,我们编写了一个名为的辅助函数merge,该函数将两个排序列表组合为一个排序列表。在类似Python的伪代码中,该函数通常如下所示:

function merge(A, B):
  C = []
  while A is not empty or B is not empty:
    if A is empty:
      C.append(B.pop())
    else if B is empty or A[0] ≤ B[0]:
      C.append(A.pop())
    else:
      C.append(B.pop())
  return C

这个想法是继续弹出和中的前几个元素中较小的一个AB直到两个列表都为空,然后将结果收集到中C。如果AB都被排序,则也是如此C

相反,if C是一个排序列表,我们将其分为任意两个子序列AB,然后AB也进行排序和merge(A, B) == C。有趣的是,如果C未排序,则不一定成立,这使我们面临挑战。

输入值

您的输入是其中一些的第一个2*n非负整数的排列,以列表形式给出。[0, 1, 2, ..., 2*n-1]n > 0C

输出量

如果存在两个列表AB长度nC == merge(A, B),则输出为真值,否则为假值。由于输入不包含重复项,因此您不必担心merge函数中的关系如何断开。

规则和奖金

您可以编写函数或完整程序。最低字节数获胜,并且不允许出现标准漏洞。

请注意,您不需要计算清单A,并B在“是”的情况。但是,如果您实际输出列表,则将获得-20%奖金。要获得此奖金,您必须仅输出一对列表,而不是所有可能性。为了使这种奖励更容易以强类型语言声明,可以在“ no”实例中输出一对空列表。

禁止暴力破解,但在不到1秒的时间内计算最后四个测试用例的总价值有-10%奖励

测试用例

在“是”实例中仅给出一个可能的输出。

[1,0] -> False
[0,1] -> [0] [1]
[3,2,1,0] -> False
[0,3,2,1] -> False
[0,1,2,3] -> [0,1] [2,3]
[1,4,0,3,2,5] -> False
[4,2,0,5,1,3] -> [4,2,0] [5,1,3]
[3,4,1,2,5,0] -> [4,1,2] [3,5,0]
[6,2,9,3,0,7,5,1,8,4] -> False
[5,7,2,9,6,8,3,4,1,0] -> False
[5,6,0,7,8,1,3,9,2,4] -> [6,0,8,1,3] [5,7,9,2,4]
[5,3,7,0,2,9,1,6,4,8] -> [5,3,7,0,2] [9,1,6,4,8]
[0,6,4,8,7,5,2,3,9,1] -> [8,7,5,2,3] [0,6,4,9,1]
[9,6,10,15,12,13,1,3,8,19,0,16,5,7,17,2,4,11,18,14] -> False
[14,8,12,0,5,4,16,9,17,7,11,1,2,10,18,19,13,15,6,3] -> False
[4,11,5,6,9,14,17,1,3,15,10,12,7,8,0,18,19,2,13,16] -> [4,17,1,3,15,10,12,7,8,0] [11,5,6,9,14,18,19,2,13,16]
[9,4,2,14,7,13,1,16,12,11,3,8,6,15,17,19,0,10,18,5] -> [9,4,2,16,12,11,3,8,6,15] [14,7,13,1,17,19,0,10,18,5]

Answers:


3

Pyth,39 * 0.9 * 0.8 = 28.08

#aY->QxQeS-QsY&YsY)KfqylTlQmsdty_Y%tlKK

该计划将所有两个奖金都囊括在内。如果可能取消合并,它将打印一对列表,否则将显示一个空列表,这是Pyth(和Python)中的虚假值。

Input:  [5,3,7,0,2,9,1,6,4,8]
Output: ([9, 1, 6, 4, 8], [5, 3, 7, 0, 2])
Input:  [5,7,2,9,6,8,3,4,1,0]
Output: [] (falsy value)

您可以在线进行测试,但可能会比离线版本慢一些。离线版本可在笔记本电脑上用不到0.15秒的时间解决每个测试用例。

Pyth解决方案可能(第一次)是主动使用Exceptions(它至少保存了1个char)。它使用与Peter Taylor解决方案相同的思想。

                         preinitialisations: Q = input(), Y = []
#                 )     while 1: (infinite loop)
        eS-QsY             finds the biggest, not previous used, number
      xQ                   finds the index
    >Q                     all elements from ... to end
   -          &YsY         but remove all used elements
 aY                        append the resulting list to Y

When all numbers are used, finding the biggest number fails, 
throws an exception and the while loop ends.  
This converts [5,3,7,0,2,9,1,6,4,8] to [[9, 1, 6, 4, 8], [7, 0, 2], [5, 3]]

        msdty_Y  combine the lists each for every possible subset of Y (except the empty subset)
 fqylTlQ         and filter them for lists T with 2*len(T) == len(Q)
K                and store them in K

%tlKK        print K[::len(K)-1] (prints first and last if K, else empty list)

Pyth,30 * 0.9 = 27.0

我还没有尝试过不打印结果列表就解决它。但是,这是一个基于上述代码的快速解决方案。

#aY->QxQeS-QsY&YsY)fqylsTlQtyY

我基本上只删除了打印语句。输出虽然很丑。

Input:  [0,1,2,3]
Output: [[[3], [2]], [[3], [1]], [[2], [1]], [[3], [0]], [[2], [0]], [[1], [0]]] (truthy value)
Input:  [5,7,2,9,6,8,3,4,1,0]
Output: [] (falsy value)

在线尝试。


您可能会发现,(K[0], Q-K[0])可以打印而不是打印(K[0], K[-1])。不过,我不知道这是否可以省钱。
彼得·泰勒

@PeterTaylor谢谢,保存了2个字符。
雅库布

@PeterTaylor甚至还有2个字符(如果我打印的话)K[::len(K)-1]
2015年

4

GolfScript(35 * 0.9 = 31.5)

{.$-1>/~,)\.}do;]1,\{{1$+}+%}/)2/&,

在线演示是相当缓慢:我的电脑上,运行所有测试下0.04秒,所以我要求减少10%。

说明

以C中最大数字开头的C后缀必须来自同一列表。然后可以将此推理应用于(C-后缀),这样问题就可以解决为子集总和。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.