安全破解澳大利亚信息学奥林匹克竞赛2009中级

时间:2017-08-25 15:58:26

标签: python algorithm python-3.x

您好,我最近在尝试AIO 2009 Intermediate的问题。

问题(改写)是:

存在一系列正整数,每个正整数通过非负常数k加密(通过向序列中的每个值添加k,并且只要a和b的以下边界,k就没有边界hold),给出一个整数列表a。给出原始非加密列表b的一小部分,使得2 <= len(b)<= 30且2 <= len(a)<= 100000。给定两个列表a和b,写一个返回原始非加密整数列表的函数。(a和b中的所有整数满足1&lt; a,b&lt; 1000000)。确保只有一个独特的解决方案。

我考虑过的一些想法是:

暴力强制b的所有可能组合,直到我们找到一个是a的子集。 (虽然我的解决方案的时间复杂度太高(O(n ^ 2)),如果有人可以编写一个O(n)解决方案,它会起作用)

找到b和a中的数字之间的差异,然后找到匹配的子集。然后我们使用它来找到b [0]对应的索引,然后导出密钥k。 (除了有一些我无法解决的角落情况外,这种情况有效)

我想知道是否有人可以使用这两种方法中的任何一种在python 3.x中编写解决方案。此外,你能解释哪种方法更好,更有效,为什么?

由于

1 个答案:

答案 0 :(得分:0)

假设您获得以下“加密”整数列表:

E1 = [200,450,100,75,275,500,600,400,300]

和解密的子列表。如下所示:

L1 = [25,225,450,550,350]

将L1转换为新数组L2,这样每个元素都是自身与前一个元素之间的差异。那是L2[i] = L1[i] - L1[i-1]。对于L2 [0],将其设为零。

L2 = [0,200,225,100,-200]

删除第一个元素(L2 = L2[1:]

L2 = [200,225,100,-200]

现在,对加密列表执行相同的规范化:

E2 = [250,-350,-25,200,225,100,-200,-100]

现在在规范化列表上进行经典的子串字符串搜索,以找到L2在E2中开始的匹配索引。

def findStartIndex(needle, haystack):
    j = 0
    while len(needle) < len(haystack[j:])
         if (needle == haystack[j:j+len(needle)]
             return j
         j = j + 1
    return -1

index = findStartIndex(L2, E2)

如果上面的搜索返回一个整数值:index(在本例中为3):

然后,密钥k只是:E1[index] - L1[0]

在此示例中,k50