📜  找出N以下所有可截短的素数之和(1)

📅  最后修改于: 2023-12-03 15:39:44.800000             🧑  作者: Mango

题目介绍

给定一个整数N,找出所有小于或等于N的可截短素数,并计算它们的和。

可截短素数指的是一个素数,从左边或右边逐步截去数字仍然是素数。

例如,23是一个可截短素数,因为它从左向右逐步截去数字后仍然是素数(23、2、3),从右向左逐步截去数字也是素数(23、2、3)。

解决方案

思路
  1. 构建一个素数列表,包含所有小于或等于N的素数;
  2. 对于素数列表中的每个素数,判断它是否为可截短素数;
  3. 如果是可截短素数,则将其加入可截短素数列表中;
  4. 计算可截短素数列表中所有数的和。
实现
构建素数列表

我们可以利用埃氏筛法来构建素数列表,具体过程如下:

  1. 构建一个长度为N+1的布尔数组is_prime[],其中is_prime[i]表示数字i是否为素数;
  2. 将is_prime[0]和is_prime[1]都设置为False;
  3. 从i=2开始循环,对于每个i:
    • 如果is_prime[i]为True,将该数的倍数is_prime[i*j](j≥2)都设置为False;
    • 如果is_prime[i]为False,跳过该数。
  4. 循环结束后,is_prime数组中为True的数字即为素数。

下面是用Python实现的素数列表构建代码:

def get_primes(n):
    is_prime = [True] * (n + 1)
    is_prime[0], is_prime[1] = False, False
    for i in range(2, int(n ** 0.5) + 1):
        if is_prime[i]:
            for j in range(i * i, n + 1, i):
                is_prime[j] = False
    return [i for i in range(n+1) if is_prime[i]]
判断可截短素数

对于一个素数,我们可以通过字符串来逐个截去数字,然后判断截去后的数是否为素数。

下面是Python代码实现:

def is_truncatable_prime(p, primes):
    str_p = str(p)
    length = len(str_p)
    for i in range(1, length):
        if not int(str_p[i:]) in primes:
            return False
        if not int(str_p[:-i]) in primes:
            return False
    return True
计算可截短素数之和

最后,我们可以利用上述函数得到所有可截短素数,并计算它们的和。

下面是Python代码实现:

def sum_truncatable_primes(n):
    primes = get_primes(n)
    truncatable_primes = [p for p in primes if is_truncatable_prime(p, primes)]
    return sum(truncatable_primes)

总结

本题考察了素数的判断、埃氏筛法等知识,同时也考察了求子字符串、列表推导式等Python编程技巧。