我正在努力为uvaonlinejudge上的3n + 1问题找到有效的解决方案。我使用的代码使用字典进行记忆。任何人都可以提出一些有助于此代码执行时间的改进吗?目前我的时间限制已超过'提交代码时出错。如果有人有解决问题的方法,请与我分享。请不要将这篇文章标记为DUPLICATE。我已经在stackoverflow上看过this帖子和其他人,但是他们没有回答这里发布的问题。我的代码如下:
import sys
def recCycleLength(n,cycLenDict):
if n==1:
return 1
if n not in cycLenDict:
if n%2==0:
cycLen = recCycleLength(n//2, cycLenDict)
cycLenDict[n] = cycLen + 1
return cycLen+1
else:
cycLen = recCycleLength(3*n+1, cycLenDict)
cycLenDict[n] = cycLen + 1
return cycLen+1
else:
return cycLenDict[n]
def maxCycle(a, b):
i = a
mydict = {}
maxLength = 1
while i <= b:
m = recCycleLength(i, mydict)
if m > maxLength:
maxLength = m
i = i + 1
return maxLength
for line in sys.stdin:
curr_line=line.split()
num1 = int(curr_line[0])
num2 = int(curr_line[1])
if num1>num2:
num1, num2 = num2, num1
m = maxCycle(num1, num2)
print("{} {} {}".format(num1, num2, m))
答案 0 :(得分:0)
我在您的代码中发现了问题。实际上,您没有保存前一个间隔中为下一个生成的cycLenDict
。这就是为什么你的代码如此“慢”的原因,因为它会一遍又一遍地产生所有可能的结局。只需将其移到全球范围内或制作如下:
import sys
def rec(n, cache):
if n in cache:
return cache[n]
if n % 2 == 0:
cycle = rec(n//2, cache)
else:
cycle = rec(3*n+1, cache)
cache[n] = cycle + 1
return cache[n]
def cycle(a, b, cache):
return max(rec(i, cache) for i in range(a, b+1))
if __name__ == '__main__':
cache = {1: 1}
for line in sys.stdin:
a, b = map(int, line.split())
a, b = min(a, b), max(a, b)
m = cycle(a, b, cache)
print("{} {} {}".format(a, b, m))
答案 1 :(得分:0)
代码似乎通过在maxCycle
中缓存所有计算结果来最佳地执行mydict
。
但是,应用程序的输入包含许多要处理的值对,maxCycle
将重置mydict = {}
并从头开始计算所有值。
我建议全局记住结果。对原始代码的简单修改将是:
cycLenDict = {} # global dictionary
def recCycleLength(n): # no cycLenDict argument
if n==1:
return 1
if n not in cycLenDict:
# ...
def maxCycle(a, b):
# ...
while i <= b:
m = recCycleLength(i) # no myDict argument
为了让所有内容看起来更好一点(与上面的解决方案相比,性能没有任何差别),请创建一个记住结果的装饰器,以便代码的其余部分不必处理:
def memoize(func):
"""decorate any function which takes positional arguments to cache its results"""
func.results = {} # results are stored globally as the funtion's attribute
def memoized(*a): # memoized version of func
if a not in func.results: # if not cached
func.results[a] = func(*a) # save to cache
return func.results[a] # return from cache
return memoized
@memoize # with this, recCycleLength is called only once for every n value
def recCycleLength(n):
if n==1:
return 1
elif n%2==0:
return recCycleLength(n//2) + 1
else:
return recCycleLength(3*n+1) + 1
def maxCycle(a, b):
return max(recCycleLength(i) for i in range(a, b+1))
答案 2 :(得分:0)
linear <- function(x, a, b) a + b*x