【问题标题】:Safe Cracking Australian Informatics Olympiad 2009 Intermediate安全破解澳大利亚信息学奥林匹克 2009 中级
【发布时间】:2017-08-25 15:58:25
【问题描述】:

您好,最近我正在尝试 AIO 2009 中级的一个问题。

问题(改写)是:

有一个正整数序列,每个正整数都通过非负常数k加密(通过将k添加到序列中的每个值,并且k没有边界,只要a和b的以下边界持有),给出一个整数列表a。我们得到原始未加密列表 b 的一小部分,使得 2

我考虑的一些想法是:

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

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

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

谢谢

【问题讨论】:

  • 加密是什么意思?异或? k 和原始整数的界限是多少?如果可以有多种解决方案怎么办?
  • @kfx 我已经编辑了问题,感谢您指出!

标签: python algorithm python-3.x


【解决方案1】:

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

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

【讨论】:

  • 我想我在示例数组中有一两个错字。今晚有空时我会更正。
  • 更新和验证。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-05-11
  • 2013-02-26
  • 2015-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多