您的位置:首页 > 其它

[Project Euler]Problem 44

2013-01-10 21:34 453 查看
Pentagonal numbers are generated by the formula, Pn=n(3n

1)/2. The first ten pentagonal numbers are:

1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...

It can be seen that P4 + P7 = 22 + 70 = 92 = P8. However, their difference, 70

22 = 48, is not pentagonal.

Find the pair of pentagonal numbers, Pj and Pk, for which their sum and difference is pentagonal and D = |Pk

Pj| is minimised; what is the value of D?

 

这道题是一个关于五角数的题目,题目意思很明白,求解这么2个数的差的绝对值。这2个数的和和差都是五角数。题目看着比较简单,但是解起来还是有点费劲的。我试过了用范围分析等等各种方法但是开始都没解出来。

这是第一种版本

#This is version 1 using brute force.
#Version 1 can't find out the answer.

l = [i*(3*i-1)//2 for i in range(1, 100000)]
pd = 9999999

for i in range(9999):
for j in range(i+1, 10000):
if l[j] + l[i] in l[j:j+i] and l[j] - l[i] in l[j:j+i]:
if l[j] - l[i] <= pd:
pd = l[j] - l[i]
print(pd)


这个版本界定了一定的范围,但是其实更加加重了其线性搜索的计算量。虽然方法没错,但是计算不出来。

 

想了很久,想出了下面的改进的方法

l = [i*(3*i-1)//2 for i in range(1, 100000)]
s = set(l)
pd = 9999999999

for i in range(9999):
for j in range(i+1, 10000):
if l[j] + l[i] in s and l[j] - l[i] in s:
if l[j] - l[i] < pd:
pd = l[j] - l[i]

print(pd)


 

使用set来代替list,因为在使用身份操作符is 的时候,set效率会比list高出很多。在list上运用is操作符,会使用线性搜索。但是set里面,set是无序的,会有更优化的搜索方式。做了个简单的测试,is运行在同样的,成员数超过10000的时候,set的时间大概值需要list的1%。

 

记住一点:当对大的数据集进行身份操作符的时候,set绝对是一个不二的选择。set,主要用于membership, 还有删除重复成员。

 

即使运用了set, 上面的代码大概也还是需要23秒左右的时间。这题计算量有点大。

 

贴一个里面的一个人的code,比较容易明白,而且更快

solved = False
pentagonalist = set()
i = 0
while solved != True:
i += 1
pnum = int(i*(3*i-1)/2)
pentagonalist.add(pnum)
for num in pentagonalist:
if pnum - num in pentagonalist and pnum - num*2 in pentagonalist:
print("the answer is:", abs(num - (pnum - num)))
solved = True
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: