50题解决中,已有简单解法,在尝试更快的版本。

This commit is contained in:
2026-03-16 18:11:11 +08:00
parent 88df32be36
commit 4c59a84d47
5 changed files with 404 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
"""
The prime 41, can be written as the sum of six consecutive primes:
41 = 2 + 3 + 5 + 7 + 11 + 13
This is the longest sum of consecutive primes that adds to a prime below one-hundred.
The longest sum of consecutive primes below one-thousand that adds to a prime, contains 21 terms,
and is equal to 953.
Which prime, below one-million, can be written as the sum of the most consecutive primes?
"""
import time
def timer(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
elapsed_time = end_time - start_time
print(f"{func.__name__} time: {elapsed_time:.6f} seconds")
return result
return wrapper
def primes_list(limit: int = 10**6) -> list[int]:
if limit < 2:
return []
is_prime = bytearray(b"\x01") * limit
is_prime[0:2] = b"\x00\x00" # 更简洁的写法同时置0和1
# 埃氏筛,使用切片赋值加速
# int(limit**0.5) 等价于 isqrt(limit)Python 3.8+ 可用 math.isqrt
for i in range(2, int(limit**0.5) + 1):
if is_prime[i]:
start = i * i
# 计算切片长度:从 start 到 limit步长 i 的元素个数
count = (limit - start + i - 1) // i # 等效于 ceil((limit-start)/i)
if count > 0:
is_prime[start:limit:i] = b"\x00" * count
return [i for i in range(limit) if is_prime[i]]
def max_primes_sum(limit: int = 10**6) -> tuple:
primes = primes_list(limit)
prime_set = set(primes)
# 计算从2开始连续加素数最多能加多少个不超过limit
max_possible_len = 0
temp_sum = 0
for p in primes:
temp_sum += p
if temp_sum >= limit:
break
max_possible_len += 1
# 从最长可能长度往下枚举
for length in range(max_possible_len, 0, -1):
# 滑动窗口计算连续length个素数的和
window_sum = sum(primes[:length])
if window_sum >= limit:
continue
# 滑动窗口遍历所有起始位置
for start in range(len(primes) - length):
if window_sum in prime_set:
return window_sum, length
# 滑动:减去头部,加上尾部
window_sum += primes[start + length] - primes[start]
if window_sum >= limit:
break
return 0, 0
@timer
def main():
limit = int(input("limit:"))
max_sum, max_length = max_primes_sum(limit)
print(f"max primt: {max_sum}, max_length: {max_length}")
if __name__ == "__main__":
main()