https://projecteuler.net/problem=14
The following iterative sequence is defined for the set of positive integers:
n → n/2 (n is even)
n → 3n + 1 (n is odd)
Using the rule above and starting with 13, we generate the following sequence:
It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.
Which starting number, under one million, produces the longest chain?
NOTE: Once the chain starts the terms are allowed to go above one million.
这个题本来想从根部1往下找,做一个深度优先搜索,写完代码才发现,小于100万的值,在趋向于的过程中产生的值会比100万大很多,而且我还没法算出来他的上限。
本来已经证明了在生成这颗树的过程中,1不重复出现,那么这棵树的所有值都不会重复。后来想想,及时我知道了上限是多少,生成的这颗树也会有很多多余的节点,也是没有太大的必要。
还是做一个字典吧,从1到100万,都算出来,然后放到字典里面去,这样也算完了,也得到了最大的值,而且中间也不会重复计算,也不会计算多余的值。
def longestChain():
#准备结果
result = 0
#准备步长最大值
maxstep = 1
#准备存储字典
stepdict = {}
#先把1放进去
stepdict[1] = 1
#从1到100万挨个计算
for i in range(1,1000000):
#只要i还没有算过,就进行计算
if i not in stepdict:
#在i通往1的过程的值都放在列表里面
templist = [i]
#获取i的下一个值
nextValue = nextChain(i)
#不停的获取下一值,直到这个值在字典中已经存在(已经计算过)
while nextValue not in stepdict:
#把还没出现值放到列表里去
templist.append(nextValue)
nextValue = nextChain(nextValue)
#获取i到1的元素个数,如果比最大步长大,就更新一下
if maxstep < stepdict[nextValue]+len(templist):
maxstep = stepdict[nextValue]+len(templist)
result = i
#把列表中所有出现过的数,都更新到字典中去,值就是步长
for i in range(0,len(templist)):
stepdict[templist[i]] = stepdict[nextValue] + len(templist) - i
return result
def nextChain(n):
if n % 2 == 0:
return n // 2
else:
return n * 3 + 1
print(longestChain())
本文探讨了一个数学问题:找出在不超过一百万的正整数中,哪个起始数能产生最长的迭代序列,序列规则为偶数除以2,奇数乘3加1,最终皆收敛于1。
97

被折叠的 条评论
为什么被折叠?



