【问题标题】:Count integers up to n that contain the digits 2018 in order [closed]按顺序计算包含数字 2018 的不超过 n 的整数 [关闭]
【发布时间】:2018-09-04 02:40:00
【问题描述】:

给定一个介于 0 和 10,0000,0000 之间的整数 n,计算小于 n 且包含数字 [2,0,1,8] 的整数个数] 为了。

例如应该计算数字 9,230,414,587,因为删除数字 [9,3,4,4,5,7] 会留下 [2,0,1,8]。

输入输出示例:

n = 2018      ->  count =     1
n = 20182018  ->  count = 92237

我的一般想法是:n 的最大长度为 10,最坏的情况是我们必须在 [2,0,1,8] 中插入 6 位数字并删除重复项和大于 n 的数字。

【问题讨论】:

  • 对不起,这听起来是一个有趣的问题,但我有点不清楚你到底想让算法做什么。你是如何得到9223720182018 数字的输出的?
  • @Alerra 抱歉解释晚了,92237< 20182018(n) 的所有号码的号码。比如20182017\20182016\20182014 这都是20182018(n) 并找到号码相遇的号码需要。
  • 一句话,数一下< n的数量,满足需求!
  • 那么,为什么20182015 不起作用但2018201620182014 起作用?很抱歉我仍然对此感到困惑。
  • @Alerra 呃..我只是想念它--,这是一些例子。我更新了关于如何定义2018 数字的描述。算法所做的是计算@987654333 @编号

标签: algorithm integer digits subsequence


【解决方案1】:

我没有看到任何自己尝试解决的方法,所以我只提供线索:

您有 9 位数字(小数字可能表示为 000002018),其中包含数字序列 2,0,1,8。
将它们命名为“好”的。
让表示从右到左从 1 到 9 的数字位置:

     number     532705183
digits     5  3  2  7  0  5  1  8  3
index      9  8  7  6  5  4  3  2  1

最左边的“2”位可以占据从 4 到 9 的位置。有多少好的数字包含第 k 个位置的第一个 2?让函数F2(l, k) 表示好数字的数量,其中2 指数字2,l 是数字长度,k 是最左边的数字。

 .   .   .   .  2   .   .   .   .
                ^ 
                | 
 left part      k     right part should contain 0 1 8 sequence
 without 2's

 F2(9, k) = 9^(9-k) * Sum(F0(k-1, j) for j=1..k-1)

好数字的总数量是所有可能 k 的 F2(9, k) 的总和。

GoodCount = Sum(F2(9, k) for k=4..9)

解释:

左边有 9-k 个地方。我们可以放除 2 以外的任何数字,所以剩下的部分可能有 9^(9-k) 个。

现在我们可以将0 放在正确的部分并计算018 子序列的可能变体。 F0(...) 当然将取决于 F1(...)F1 将取决于 F8(...) 以获得更短的数字。

因此,请逐步填写表格以获取 F8, F0, F1 的值,最后计算数字 2 的结果。

包含子序列1 8k = 第一个'1'的位置的4位数字的手工示例:
k=2: 有81种数字xx18
k=3:有 x1x8x18x 的数量
有 9 个子编号,如 x8,10 个子编号 8x,所以 (10+9)*9=171
k=4:有种类的数字
1xx8(9*9=81 个数字),
1x8x(9*10=90 个数字),
18xx(100 个数字) ,
所以 81+90+100=271
总体:81+171+271=523

【讨论】:

  • 感谢您的回答,但您的回答有点难以理解,仍然感谢您的时间。我仍然无法理解 F 函数。
  • 我稍微改写了我的答案
  • 我明白了!您定义了一种计算最终结果的方法。
【解决方案2】:

这实际上是一个相对的问题集。如果数字更大,我会选择使用优化的技术来生成所有符合您标准的数字(那些包含按该顺序排列的数字),而不是生成 所有 可能的数字和 检查每个以确保它符合标准。

但是,蛮力方法在大约 10 秒内完成您的 20182018 变体,并在不到 8 分钟内完成整个 1,000,000,000 范围。

因此,除非您需要比这更快的速度,否则您可能会发现蛮力方法绰绰有余:

import re

num = 1000000000 # or 20182018 or something else.

lookfor = re.compile("2.*0.*1.*8")
count = 0
for i in range(num + 1):
    if lookfor.search(str(i)) is not None:
        count += 1
        #print(count, i) # For checking.
print(count)

【讨论】:

  • 感谢您的回答,我确实想找到一种更快的方法!
猜你喜欢
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
  • 1970-01-01
  • 2014-06-23
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多