我的代码效率低下,是来自 Project Euler 的 3 和 5 的倍数,但有 10 秒的超时条件

And*_*ong 2 python python-3.x

问题陈述

\n\n
\n

此问题是来自projecteuler.net 的问题 1 的编程版本

\n\n

如果我们列出 10 以下所有 3 或 5 的倍数的自然数,我们会得到 3、5、6 和 9。这些倍数的总和是 23。

\n\n

求 N 以下所有 3 或 5 的倍数之和。

\n
\n\n

输入格式

\n\n
\n

第一行包含 T 表示测试用例的数量。接下来是 T 行,每行包含一个整数 N。

\n
\n\n

输出格式

\n\n
\n

对于每个测试用例,打印一个整数,表示 N 以下所有 3 或 5 的倍数之和。

\n
\n\n

约束条件

\n\n
1\xe2\x89\xa4T\xe2\x89\xa4105 \n1\xe2\x89\xa4N\xe2\x89\xa4109\n
Run Code Online (Sandbox Code Playgroud)\n\n

输入样本

\n\n
2\n10\n100\n
Run Code Online (Sandbox Code Playgroud)\n\n

样本输出

\n\n
23\n2318\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

我正在做第一个欧拉项目问题,但有时间限制,需要接受额外的挑战。如果该过程花费超过 10 秒,它将自动失败。

\n\n

这是一个示例输入:

\n\n
2   # number of test cases\n10  # first test case\n100 # second test case\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的代码:

\n\n
test_case = int(input())\nfor x in range(0, test_case):       # Loops after every test case\n    stop_value = int(input())\n\n    answer = 0\n\n    threes = 0\n    while threes < stop_value:      # Checks 3s\n        answer += threes\n        threes += 3\n\n    fives = 0\n    while fives < stop_value:       # Checks 5s\n        answer += fives\n        fives += 5\n\n    commons = 0\n    while commons < stop_value:     # Check 15s\n        answer -= commons\n        commons += 15\n\n    print(answer)\n
Run Code Online (Sandbox Code Playgroud)\n\n

该问题在对我的解决方案进行评分时不会向我显示输入,但我假设其中一个测试用例正在检查,直到10^9运行时间超过 10 秒。

\n\n
\n\n

之前的尝试注意:最初我有一个更简单的代码,它运行一个 for 循环,0一旦变得太大stop_value就会失败stop_value,所以我尝试在所有内容之间跳过 while 循环(我上面显示的)。

\n\n
\n\n

下一步尝试:

\n\n

我试图找到每个数字的最大倍数以及该项乘以它们自己的阶乘的倍数,但我得到了错误的输出。

\n\n

为了解释我的思考过程,我以 10 为例,10//3 = 3。如果我做 3!*3,那么[1*3,2*3,3*3]=[3,6,9]是 3 的所有倍数stop_value:我注意到这是错误实现的,我目前正在考虑阶乘的 for 循环。

\n\n
import math\n\ntest_case = int(input())\nfor x in range(0, test_case):       # Loops after every test case\n    stop_value = int(input())\n\n    threes = stop_value // 3\n    fives = stop_value // 5\n    commons = stop_value // 15\n\n    answer = math.factorial(threes)*3 + math.factorial(fives)*5 - math.factorial(commons)*15\n\n    print(answer)\n
Run Code Online (Sandbox Code Playgroud)\n\n

您的输出(标准输出)

\n\n
13\n26049952856435659498719093244723189200\n
Run Code Online (Sandbox Code Playgroud)\n\n

预期输出

\n\n
23\n2318\n
Run Code Online (Sandbox Code Playgroud)\n

pok*_*oke 5

这是自然数之和的推广。步长k和最大数n(可被n整除k)的一般公式为:n / k / 2 * (n + k)

def euler1 (n):
    max3 = range(0, n, 3)[-1]
    max5 = range(0, n, 5)[-1]
    max15 = range(0, n, 15)[-1]

    sum3 = (max3 + 3) * max3 // 3 // 2
    sum5 = (max5 + 5) * max5 // 5 // 2
    sum15 = (max15 + 15) * max15 // 15 // 2

    return sum3 + sum5 - sum15
Run Code Online (Sandbox Code Playgroud)
>>> euler1(10)
23
>>> euler1(100)
2318
>>> euler1(10**100)
23333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333331666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666668
Run Code Online (Sandbox Code Playgroud)