蓝桥杯2022国赛|选素数 Python

在这里插入图片描述

这个题主要考察质因数分解质数判断,构建出合理的、高效的算法还是需要动脑子的。
带有详细注释的代码如下,我相信仔细耐心阅读,便能成功理解。
下面叙述假设: a0 -> a1 -> a2(依次进行第一次操作、第二次操作)

import math
import time

#判断是否为素数
def is_prime(x):
    upper_bound = int(math.sqrt(x)) + 1
    for i in range(2, upper_bound):
        if x % i == 0:
            return False
    return True
#对指定数进行质因数分解,递归实现。
def fact(n, primes):
    for i in range(2, int(n ** 0.5) + 1):
        if n % i == 0:
            primes.append(i)
            fact(n // i, primes)
            return
    primes.append(n)


n = int(input())

#如果输入数为质数,那么打印-1。因为我们的n应该是质数的倍数,
#且必须至少为2倍(题目中说了选择一个小于 x的素数p,所以至少是2倍)。  ------①
if is_prime(n):
    print(-1)
else:
    primes = []
    fact(n, primes)   #对其质因数分解

    prime_set = set(primes)  #将质因数转为集合(无重复元素)

    min_start = 1000001

    for prime in prime_set:  #遍历质因数集合
        last_left_Bound = n - prime  #假设第二次操作选择的是prime作为质数,那么第二次操作前的数(a1)不会小于n-prime。
        # print(last_left_Bound)
        #上次操作前的数字(a1)必然在左边界加1和n之间。(为什么是n?因为n可能本身就是某
        #个质数的倍数,然后这次操作又选了该质数,则n不变)
        for last_num in range(last_left_Bound + 1, n + 1):#对第一次操作后可能的数组遍历
            if is_prime(last_num):  #和①同理,不可能是质数。
                continue
            prime_tmp = []
            fact(last_num, prime_tmp)	#继续对上个数进行质因数分解
            max_gap = max(prime_tmp)    #找出最大的质因数作为第一次操作选择的质数,
                                        #这样能使起始数字尽可能小
            min_start = min(last_num - max_gap + 1, min_start) #更新维护最小数字

    if min_start == 1000001:
      print(-1)
    else:
      print(min_start)

比较关键的地方在于,我们在第二个内层循环分析时,要用第一次操作后可能得到的数字a1减去其最大的质因数,即第一次操作我们选择的质数是a1的最大质因数,这样才能让a0尽可能小。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值