问题(来源于:http://projecteuler.net/problem=5):
2520是最小的能被1-10中每个数字整除的正整数。
最小的能被1-20中每个数整除的正整数是多少?
解决问题的算法:
要用于的基础原理:任何合数都可以用有限个质数的积来表示。
我们用N来表示问题的结果值,即N可以用1...20之间的质数之积来表示。
所以,我们可以首先找到1...20之间所有的质数,然后再找出每个质数要用到的次数
接着求出每个质数的相应次方,最后把上步求出的值全部相乘即是结果。
举例:
用p[i]数组表示所有的质数,a[i]表示与p[i]下标对应的质数的个数,^表示乘方,
则结果N就等于:
N=(p[0]^a[0]) * (p[1]^a[1]) * (p[2]^a[2]) * ...
结果值:232792560
注意:不要从1(或者2520)开始枚举,一直到结果出来。因为你根本就不知道结果为多少,
那么到底要枚举到什么值呢?我们把1...20这些数相乘,得出有2432902008176640000
大概有2432902万亿左右),这是无法想像的!而结果值却是有2.3亿左右,也就是说,
我们至少要枚举2.3亿次左右;对于我们平常人用的PC机,慢的话,可能要用几个小时,几十小时,
甚至几天吧!
2520是最小的能被1-10中每个数字整除的正整数。
最小的能被1-20中每个数整除的正整数是多少?
解决问题的算法:
要用于的基础原理:任何合数都可以用有限个质数的积来表示。
我们用N来表示问题的结果值,即N可以用1...20之间的质数之积来表示。
所以,我们可以首先找到1...20之间所有的质数,然后再找出每个质数要用到的次数
接着求出每个质数的相应次方,最后把上步求出的值全部相乘即是结果。
举例:
用p[i]数组表示所有的质数,a[i]表示与p[i]下标对应的质数的个数,^表示乘方,
则结果N就等于:
N=(p[0]^a[0]) * (p[1]^a[1]) * (p[2]^a[2]) * ...
结果值:232792560
注意:不要从1(或者2520)开始枚举,一直到结果出来。因为你根本就不知道结果为多少,
那么到底要枚举到什么值呢?我们把1...20这些数相乘,得出有2432902008176640000
大概有2432902万亿左右),这是无法想像的!而结果值却是有2.3亿左右,也就是说,
我们至少要枚举2.3亿次左右;对于我们平常人用的PC机,慢的话,可能要用几个小时,几十小时,
甚至几天吧!
# Python 3.X 程序
# Author:Sangay
# Date:12/10/2012
import math
k=20 # 定义一个1...k
p=[] # 定义一个列表,用以保存1...k以内(包括k)的所有质数
N=1 # 用来保存结果值
# 以下循环用来找出所有的质数并放到列表p当中
for x in range(2, k+1):
c=True
for y in range(2, math.floor(math.sqrt(x))+1):
if x%y == 0:
c=False
break
if c:
p.append(x)
print(p) # 查看一下都有哪些质数
lenght=len(p) # 质数的个数
a=list(range(lenght)) # 用以保存对应的质数所使用的次数,也即是结果N中相应的质数因子的个数
# 即:a[2]保存的是p[2]中所保存的质数的个数
b=list(range(lenght)) # 临时变量,与列表a对应
# 以下循环用来找出列表p中所保存的质数的个数,即相应下标的列表a的值
for x in range(lenght):
a[x]=b[x]=0
for x in range(2, k+1):
for y in range(lenght):
z=x
b[y]=0
while True:
if z%p[y] == 0:
b[y]+=1
z/=p[y]
else:
break
if a[y] < b[y]:
a[y]=b[y]
print(a) # 查看相应质数的个数
# 计算结果值,即:N=(p[0]^a[0]) * (p[1]^a[1]) * ...。其中^表示乘方
for x in range(lenght):
N*=p[x]**a[x]
print("result: ",N) # 查看结果值