如何用一定数量的除数计算最小数?

Col*_*nic 15 algorithm math

来自Project Euler问题500

120的除数是16.事实上,120是具有16个除数的最小数.

找到2**500500除数的最小数字.给出你的答案模500500507.

这很简单,可以计算n的除数,例如.在Python中len([i for i in range(1,n+1) if n % i == 0]).这是O(n).

我尝试了强力搜索,发现32个除数的最小数是840,但对于上面的问题来说太慢了.从不平等的角度来看count_divisors(n) <= n,这个数字将是巨大的.

你怎么看?有任何想法吗?如何用一定数量的除数计算最小数?


编辑:我不认为这是重复的.这个问题是更具体的,它涉及一类特殊的更大的数字.在其他问题通常要求.它的答案不适用于这个问题,它的大小不同.

Mil*_*kic 12

你应该使用整数除数的公式n:

d(n)=(a 1 +1)(a 2 +1)...(a k +1)

哪里

n = p 1 a 1*p 2 a 2*p 3 a 3*...*p k a k

是通过其主要除数的每个整数的唯一表示.这是一个著名的公式,但如果人们不知道如何得到它,注意dn当且仅当d是形式的P 1 X 1*P 2 X 2*P 3 X 3*......*P ķ X k,其中x i中的每一个在0和a i之间,因此存在用于选择x i中的每一个的i + 1种可能性.现在只需应用产品规则即可获得所需的公式.

对于固定d(n)(如在您的情况下),n显然通过仔细选择现有素数的幂或通过添加新素数来获得最小值.让我们通过这个简单的例子,16:

d(x)=(a 1 +1)(a 2 +1)...(a k +1)= 16 = 2 4.

这意味着您最多有4个不同的素数,因此:

x = 2 a 1*3 a 2*5 a 3*7 a 4

其中a i > = 0.现在的问题是 - 为了获得最小值x,增加2的幂(即增加1)或使用7(即取4 = 1代替a 4 = 0)?好吧,检查很简单,2*3*5*7> 2 3*3*5 = 120,这就是120在这种情况下回答的原因.

如何推广这种方法?你应该创建min-heap,你将放置素数的幂,注意除数的数量达到指定值.在16的情况下,该最小堆将包含数字2,3,5,7,2 2,3 2,2 4等为什么?因为16 = 2 4,所以每个(a i +1)必须除以16,即它必须是2的幂.每当你增加新的功率时,它应该增加左手边(即变量d(x))由2的幂,因为你的最终目标是找到2 500500除数的最小数字.使用第一个k素数(在问题语句中k = 500500)初始化堆,并且在每个步骤中,当您从堆中弹出p x时,返回p 2x并将结果乘以p x.d(x)= 16 = 2 4的逐步解决方案:

Step    Heap    d(x)    x
==========================
0      2,3,5,7    1     1
1      3,4,5,7    2     2
2      4,5,7,9    4     6
3      5,7,9,16   8     24
4      7,9,16,25  16    120
Run Code Online (Sandbox Code Playgroud)

HTH.

  • 整齐!你解释得很好.这正是我用最小堆计算它的方式. (3认同)