使用函数

时间:2015-08-12 19:09:52

标签: python algorithm function python-3.x

我正在编写一个代码,用于计算下面函数g(x)中与自然数相关的差距,然后将它们相加。

from math import *

a = set()
n = eval(input("n = "))

def g(x):
    return floor(x*log10(x))   # thanks to tzaman

b = 1
while g(b) < n:
    a.add(g(b))
    b+=1

aprime = set(range(max(a)))

z = max(a)

print(z*(z+1)/2-sum(a))        # thanks to tzaman

input("Done!")

我正在尝试n = 10 ** 10,即10000000000,并在合理的时间内执行计算(例如,<10分钟)。但是,这段代码执行起来很荒谬,我想知道:有没有更有效的方法呢?

示例I / O

n = 12, output = 15

其他信息

以下图表将xg(x)进行了比较:

 x   | 1 2 3 4 5 6 7 8 9 10 11 12
g(x) | 0 0 1 2 3 4 5 7 8 10 11 12

集合x \ g(x)代表x中不在g(x)的成员,对于低于12的数字{0,6,9};这些的总和是15.所以,当n = 12output = 15

2 个答案:

答案 0 :(得分:1)

您的麻烦可能来自sum(aprime-a)行。这会强制python计算两组的集合差异。考虑到您的设置有多大,这会浪费很多时间。

sum(a-b) = sum(a)-sum(b)b的子集时(而不是你的情况),请注意a。所以我们现在有sum(aprime)-sum(a)

接下来利用aprime只是算术序列的事实!你有一个公式来计算这些东西的总和!而不是sum(aprime)你可以做

maxVal = max(a)
sumAPrime = ((maxVal +1)*maxVal)/2

所以你现在有sumAPrime - sum(a)作为你的解决方案!

我将假设您需要优化以适用于任意函数g,因此您无法对代码中的函数进行假设。

希望这有帮助! :)

答案 1 :(得分:1)

我不确定它会有多大影响,但您可以阻止使用set()eval()eval()可以更改为int(),因为您已将n =设置为输入结果。接下来,您可以在迭代中检查g中的g(b)的值。删除aprime并将a更改为列表将提供以下内容。

from math import *

a = []
n = int(input("n = "))

def g(x):
    return floor(x*log10(x))

b = 1
while g(b) < n:
    if g(b) in a:
        b+=1
    else:
        a.append(g(b))
        b+=1

z = max(a)

print(z*(z+1)/2-sum(a))

input("Done!")