51题完成解决

This commit is contained in:
2026-03-18 18:14:55 +08:00
parent f6f88a9e9d
commit be30320454
2 changed files with 299 additions and 0 deletions

View File

@@ -0,0 +1,105 @@
"""
By replacing the 1st digit of the 2-digit number *3,
it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.
By replacing the 3rd and 4th digits of 56**3 with the same digit,
this 5-digit number is the first example having seven primes among the ten generated numbers,
yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993.
Consequently 56003, being the first member of this family, is the smallest prime with this property.
Find the smallest prime which,
by replacing part of the number (not necessarily adjacent digits) with the same digit,
is part of an eight prime value family.
-----
*.000*.、*.111*.、*.222*.、*.333*.、*.444*.、*.555*.、*.666*.、*.777*.、*.888*.、*.999*.
数字的形式就是这样,最多十个数,那么,就是要在质数序列上搜索这样的数列:
1. 用欧拉筛生成质数表上限约100万足够
2. 对每个质数p
a. 检查是否有≥3个相同数字且该数字∈{0,1,2}
b. 生成所有C(n,3)种3位替换组合
c. 对每种组合用0-9替换统计质数个数
d. 若得到8个质数返回p首个即为答案
"""
import time
from itertools import combinations
from math import isqrt
from bitarray import bitarray
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**8) -> set[int]:
is_prime = bitarray(limit + 1)
is_prime.setall(True)
is_prime[:2] = False # 0和1不是素数
# 只需筛到 sqrt(n)
imax = isqrt(limit) + 1
for i in range(2, imax):
if is_prime[i]:
# 步长i从i*i开始小于i*i的已被更小的素数筛过
is_prime[i * i : limit + 1 : i] = False
return {i for i, isp in enumerate(is_prime) if isp}
@timer
def solve() -> list[int]:
primes = primes_list(10**6)
# 遍历所有可能的模式
for prime in sorted(primes):
if prime < 1000: # 从4位数开始
continue
s = str(prime)
# 检查每个出现3次或以上的数字
for d in set(s):
positions = [i for i, c in enumerate(s) if c == d]
if len(positions) < 3:
continue
# 尝试替换3个位置
for combo in combinations(positions, 3):
if 0 in combo and d == "0":
continue
family = []
for new_d in "0123456789":
new_num_str = "".join(
new_d if i in combo else c for i, c in enumerate(s)
)
new_num = int(new_num_str)
# 确保长度相同且是素数
if len(str(new_num)) == len(s) and new_num in primes:
family.append(new_num)
if len(family) == 8:
return sorted(family)
return [-1]
if __name__ == "__main__":
result = solve()
print(result)