【问题标题】:Recreate the Sequence重新创建序列
【发布时间】:2014-05-06 09:35:03
【问题描述】:

我遇到了以下问题,从那时起我就一直在想这个问题:

Alice 在黑板上写了N 连续的正整数。例如。 "99, 100, 101, 102"。 Bob 已经从每个数字中删除了所有数字,但只有一个,因此序列现在读取例如"9, 0, 0, 1"。请注意,他留下的数字对于每个整数都可以是不同的。

我们的任务是,以O(N log N) 时间复杂度,找到可能启动序列的最小数字。在上面的例子中,答案是99。对于长度为 7 的序列 "1, 4, 0, 5, 4, 1, 4" ,答案将是 1042。 (产生序列 1042、1043、1044、1045、1046、1047、1048)。

我可以显示大约1234567890*N 的上限,因此输出不能是无限大小。但是我什至找不到有效的O(N^2) 解决方案。

有什么想法吗?

【问题讨论】:

  • "我可以显示大约 1234567890*N 的上限" 你是什么意思?对于所有可能的输入,结果小于 1234567890*N?
  • 哦,我明白了。我以为只剩下最后一个数字,但事实并非如此。
  • @AlmaDo 我认为 arbitrary 会是更好的术语。 Bob 是一个对手,他会删除他喜欢的任何数字,可能会使其变得特别困难
  • @AlmaDo 是的,完全正确。但是random这个词在数学中有一个非常具体的含义,在这里并不适用,这就是为什么我建议arbitrary
  • 你能告诉我们这个问题的根源吗?你确定它可以在 O(N log N) 中解决吗?

标签: algorithm integer sequence


【解决方案1】:

更新:对于那些感兴趣的人,这个问题出现在Baltic Olympiad in Informatics (BOI) 2014(这是任务“序列”)。 Due to Codeforces user Fdg,这是一个 O(N log N) 解决方案:尝试每个可能的起始值的最后一位。将连续的数组元素划分为末尾具有数字 0 到 9 的组(这可以从起始值的最后一个数字推断出来)。我们知道,同一组中的所有值都具有相同的前缀,在我们删除它们的最后一位之后。让我们根据它们的位置消除输入中的数字与它应该具有的最后一个数字匹配的所有值。

现在我们有一个稍微不同的子问题:对于每组 10 个,我们知道出现在其前缀中的 set 个数字。我们将其折叠成单个数组元素。这个广义问题的大小只有原始问题的十分之一,并且可以使用相同的算法递归求解。

因此我们得到递归 T(N) = 10 * T(N / 10) + O(N),我们使用主定理将其求解为 T(N) = O(N log N)。

示例:

假设输入是[1, 4, 0, 5, 4, 1, 4, 9, 5, 0, 1, 0]。因此,在广义形式中,我们知道每个位置的以下数字子集:

{1} {4} {0} {5} {4} {1} {4} {9} {5} {0} {1} {0}

我们检查数字2 作为起始数字的最后一位(当然我们也检查所有其他数字,但这个分支将包含最小解决方案)。我们知道最后一位数字的顺序是这样的

2  3  4  5  6  7  8  9  0  1  2  3

所以我们知道具有相同前缀(2-9 和 0-3)的组。我们还从我们已经知道在正确位置的集合中消除那些数字:

{1} {4} {0} {} {4} {1} {4} {} | {5} {0} {1} {0}

通过收集每组的所有数字,我们得到了约简问题

{0,1,4} {0,1,5}

我们再次暴力破解倒数第二个数字。假设我们正在检查4。我们得到:

  4     5
{0,1} {0,1}

减少到

{0,1}

现在我们只剩下一个数组元素,我们只需要从那些没有前导零的数字中构建字典序上最小的数字,即10。所以结果是1042

旧版

我相信这里的一个关键观察结果是,在这样一个长度为 N 的进程中,只有最后一个 ceil(log_10(N)) 数字被多次更改。所以我们可以暴力破解最后的 ceil(log_10(N)) 个数字,前缀末尾的九个数和 O(N * log N) 之前的数字。

所以我们修复了模式

P..PX9..9S...S

其中后缀 S 已知,九的个数已知,X

我们现在可以从序列中删除那些已经与我们已经知道出现在它们各自位置的数字之一匹配的数字。我们剩下一组数字,我们知道它们包含前缀 P。我们只是形成字典上最小的字符串,它没有前导零并包含所有数字。

运行时间为 O(N^2 log N)。

【讨论】:

  • 这并不能保证可能的最小数字,因为您可以删除 D[j]-D[i] mod 10 = j-i,正如我在回答中所建议的那样。
  • @Nick 我们似乎误会了对方。我的建议是以系统的方式枚举 所有 候选者,因此您当然也会找到最小的解决方案。诀窍是如何将候选集缩小到可管理的规模
  • 我认为如果你想达到 N log N 运行时,这正是你不应该做的。
  • 如何确定最后一个 log(N) 位数?最大化每个数字的长度序列?
  • @Bentoy13 嗯,这是[算法],不是收集选票的最佳场所:)
猜你喜欢
  • 2017-10-09
  • 1970-01-01
  • 2021-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 2012-06-15
  • 1970-01-01
相关资源
最近更新 更多