Python 求(N!)^2的除数
我试图解决问题,我将其简化为: 求N的除数^二, 我编写了我的解决方案,我把它作为一个答案放在这里,因为我没有被指责没有做任何工作,它对大数字也能正常、快速地工作,但是由于超时,它没有通过所有测试,我认为我的算法效率不高 以下是我的想法概要: 任何数字都可以表示为a0^b1*a1^b1*..*an^bn,其中有1+b1*1+b2*..*1+bn除数 那么M^2将有1+2b1*1+2b2*..*1+2bn除数 创建一个函数,用于查找数字的所有因子并将它们保存为hashmap 有一个函数,通过添加相应键的值来组合两个哈希映射 使用这两个函数迭代从2到n的所有数字,以获得阶乘的所有除数 使用1中的函数。得到答案 我认为这个解决方案相当有效,但似乎有更好的方法。Python 求(N!)^2的除数,python,algorithm,math,Python,Algorithm,Math,我试图解决问题,我将其简化为: 求N的除数^二, 我编写了我的解决方案,我把它作为一个答案放在这里,因为我没有被指责没有做任何工作,它对大数字也能正常、快速地工作,但是由于超时,它没有通过所有测试,我认为我的算法效率不高 以下是我的想法概要: 任何数字都可以表示为a0^b1*a1^b1*..*an^bn,其中有1+b1*1+b2*..*1+bn除数 那么M^2将有1+2b1*1+2b2*..*1+2bn除数 创建一个函数,用于查找数字的所有因子并将它们保存为hashmap 有一个函数,通过添加相
有谁能给我推荐一个更好的方法吗?你的问题有一个简单有效的解决方案。注意n!是: 让我们想想一个主要因素在这个产品中出现了多少次,例如2。 每2个因素出现一次。但每四个因素中就有一个会出现两次。每8个因素出现一次三次等。 换句话说,因子2将出现在n中!sumn//2**e代表范围1中的e,n次。对于任何素因子k也是如此 您可以通过以下方式实现此计算:
import itertools as it
def exp_for_factor_in_factorial(factor, n):
total = 0
for e in it.count(1):
if factor ** e > n:
break
total += n // factor**e
return total
现在,为了找到n的所有素因子!我们需要找到n以下的所有素数,这很容易用埃拉托斯烯实现:
import math
def sieve(n):
nums = [True] * (n+1)
nums[:2] = [False]*2
nums[4::2] = [False] * math.ceil((n-3)/2)
for i in range(3, int((n+1)**.5)+1, 2):
if nums[i]:
for j in range(i*i, n+1, 2*i):
nums[j] = False
return [i for i,k in enumerate(nums) if k]
这使得我们可以得到n的因式分解:
最后,要计算因式分解的除数,可以使用前面提到的公式:
import operator as op
from functools import reduce
def get_num_divisors(factorization):
return reduce(op.mul, (e+1 for _, e in factorization), 1)
因此,最终的答案是:
def divs_of_squared_fact(n):
return get_num_divisors((p, 2*e) for p, e in get_factorization_factorial(n))
请注意,此解决方案的性能远远高于您的:
In [41]: %%timeit
...: for i in range(2, 1000):
...: x = divs_of_squared_fact(i)
...:
1 loops, best of 3: 276 ms per loop
In [42]: %%timeit
...: for i in range(2, 1000):
...: x = divisorsOfFactorialSquare(i)
...:
1 loops, best of 3: 7.89 s per loop
它能够产生5000个除数^大约2毫秒内完成2次,而另一次几乎需要半秒:
In [47]: %timeit divs_of_squared_fact(5000)
100 loops, best of 3: 2.07 ms per loop
In [48]: %timeit divisorsOfFactorialSquare(5000)
1 loops, best of 3: 439 ms per loop
事实上,答案具有不同的渐近复杂性,因此当增加参数时,差异会无穷大。对于此类问题,您可能会在@Vektor88上找到更好的答案。我考虑过这个问题,也考虑过代码审查,但我相信这是一个更好的地方。我不是反对者,但我真的认为,当涉及到性能或复杂性时,CS是一个更好的地方。但这只是一个建议。你肯定比我更了解和使用这个网站:谢谢你花时间写下这个详细的解释。解释和实现非常出色。
In [41]: %%timeit
...: for i in range(2, 1000):
...: x = divs_of_squared_fact(i)
...:
1 loops, best of 3: 276 ms per loop
In [42]: %%timeit
...: for i in range(2, 1000):
...: x = divisorsOfFactorialSquare(i)
...:
1 loops, best of 3: 7.89 s per loop
In [47]: %timeit divs_of_squared_fact(5000)
100 loops, best of 3: 2.07 ms per loop
In [48]: %timeit divisorsOfFactorialSquare(5000)
1 loops, best of 3: 439 ms per loop