50题解决了,使用了动态上限,优化了搜索。

This commit is contained in:
2026-03-17 17:52:50 +08:00
parent 3358e97dd4
commit f6f88a9e9d

View File

@@ -10,7 +10,7 @@ Which prime, below one-million, can be written as the sum of the most consecutiv
""" """
import time import time
from math import isqrt, log from math import isqrt, log, sqrt
from bitarray import bitarray from bitarray import bitarray
@@ -88,26 +88,31 @@ def is_prime(num: int) -> bool:
return True return True
def get_bound_dynanic(N, iterations=3):
# 初始猜测(基于简化公式)
k = sqrt(2 * N / log(N)) if N > 100 else 10
# 牛顿法迭代3次足够
for _ in range(iterations):
ln_k = log(k)
# f(k) = k^2 * ln_k - 2N, f'(k) = k * (2*ln_k + 1)
k = (k**2 * (1 + ln_k) + 2 * N) / (k * (2 * ln_k + 1))
return int(k) # 返回安全上界如562
def get_bound(limit: int = 10**6) -> int: def get_bound(limit: int = 10**6) -> int:
""" """
使用牛顿法估算筛法所需的素数上限。 估算素数个数上限。
""" """
return int(isqrt(int(2 * limit / log(limit))) * 1.55)
def f(t: float) -> float:
return t**2 * (2 * log(t) - 1) - 2 * limit
def fp(t: float) -> float:
return 4 * t * log(t)
x, y = limit, limit + 2
while y - x > 1:
y, x = x, x - f(x) / fp(x)
return int(x * (log(x) + log(log(x) - 1)))
@timer
def max_primes_sum_best(limit: int = 10**6) -> tuple[int, int] | None: def max_primes_sum_best(limit: int = 10**6) -> tuple[int, int] | None:
# === 1. 确定搜索范围 === # === 1. 确定搜索范围 ===
bound = get_bound(limit) bound = get_bound_dynanic(limit)
print(f"bound: {bound}")
primes = n_primes(bound) primes = n_primes(bound)
# === 2. 构建前缀和数组 === # === 2. 构建前缀和数组 ===
@@ -157,7 +162,6 @@ def max_primes_sum_best(limit: int = 10**6) -> tuple[int, int] | None:
return best_prime, best_length return best_prime, best_length
@timer
def main(): def main():
limit = int(input("limit:")) limit = int(input("limit:"))
max_sum = max_primes_sum_best(limit) max_sum = max_primes_sum_best(limit)