AcWing 4268性感素数

性感素数 ”是指形如 $(p, p+6)$ 这样的一对素数。之所以叫这个名字,是因为拉丁语管“六”叫“sex”(即英语的“性感”)。现给定一个整数,请你判断其是否为一个性感素数。

输入格式

输入在一行中给出一个正整数 $N$。

输出格式

若 $N$ 是一个性感素数,则在一行中输出 Yes,并在第二行输出与 $N$ 配对的另一个性感素数(若这样的数不唯一,输出较小的那个)。

若 $N$ 不是性感素数,则在一行中输出 No,然后在第二行输出大于 $N$ 的最小性感素数。

数据范围

$1 \leqslant N \leqslant 10^8$

输入样例1:

47

输出样例1:

Yes

41

输入样例2:

21

输出样例2:

No

23

思路:

1.本题解决的关键点是判断素数问题。

2.判断质数可以采取两种方法。

  • 一种是最朴素的方法是按素数的定义,试除以从2开始到m-1的整数,如果无一例外地不能整除,则该数一定是素数。同时根据数m若有因子则一个比小于这个数的平方根,而另一个必定大于,因此可将判断范围进一步缩小一半。
def isPrime(x):
    if x < 2:
        return False
    t = int(power(x, 0.5)) # 或 t = int(0.5 ** x)
    for i in range(2,  t + 1):
        if x % i == 0:
            return False
    return True
  • 另一种则是利用素数的性质进行判断。该性质是质数有一个特点,就是它总是等于 6x-1 或者 6x+1,其中 x 是大于等于1的自然数。

具体证明:首先 6x 肯定不是质数,因为它能被 6 整除;其次 6x+2 肯定也不是质数,因为它还能被2整除;依次类推,6x+3 肯定能被 3 整除;6x+4 肯定能被 2 整除。那么,就只有 6x+1 和 6x+5 (即等同于6x-1) 可能是质数了。所以循环的步长可以设为 6,然后每次只判断 6 两侧的数即可。

def isPrime(num):
    if num <= 3:
        return num > 1
    if num % 6 in (0, 2, 3, 4):
        return False
    i, t = 5, int(num**0.5)
    while i <= t:
        # 此时的 num 确定是 6x+1 或者 6x-1 ,那么直接用 6x 左右的数字去除这个数(左边 = 6x-1,右边 = (6x-1)+ 2),
        # 能够整除则一定不是素数
        if num % i == 0 or num % (i + 2) == 0:
            return False
        i += 6
    return True

完整Python代码:

def isPrime(num):
    if num <= 3:
        return num > 1
    if num % 6 in (0, 2, 3, 4):
        return False
    i, t = 5, int(num**0.5)
    while i <= t:
        if num % i == 0 or num % (i + 2) == 0:
            return False
        i += 6
    return True


def find(num):
    if isPrime(num) and (isPrime(num - 6) or isPrime(num + 6)):
        print("Yes")
        if isPrime(num - 6):
            print(num - 6)
        else:
            print(num + 6)
    else:
        i = num
        while True:
            i = i + 1
            if isPrime(i) and (isPrime(i - 6) or isPrime(i + 6)):
                print('No')
                if isPrime(i - 6) and i - 6 > num:
                    print(i - 6)
                else:
                    print(i)
                break


def main():
    n = int(input())
    find(n)


if __name__ == '__main__':
    main()
posted @ 2022-06-10 17:18  devon-dlq  阅读(26)  评论(0)    收藏  举报