50题解决了,使用了动态上限,优化了搜索。
This commit is contained in:
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user