<蓝桥杯>超级质数


原题链接

超级质数


一、题目描述

如果一个质数 P 的每位数字都是质数, 而且每两个相邻的数字组成的两位 数是质数, 而且每三位相邻的数字组成的三位数是质数, 依次类推, 如果每相 邻的 k 位数字组成的 k 位数都是质数, 则 P 称为超级质数。

如果把超级质数 P 看成一个字符串, 则这个超级质数的每个子串都是质 数。

例如, 53 是一个超级质数。

请问, 最大的超级质数是多少?

简单来说就是判断一个数字所有子串是否是质数。

由题可知,使用暴力枚举判断任意一个数是否是超级质数的复杂度大约
O( ( n 2 + n ) − 3 2 (n^2+n)^\frac{-3}{2} (n2+n)23)
显然暴力枚举行不通。

二、思路

使用[2,3,5,7]四个数生成数字,将生成的数字按其位数分成不同阶段,个位数是一个阶段,十位数是一个阶段,每个阶段符合超级质数要求的数字都放入prime数组中,prime[i][j]表示 i 阶段产生的集合中的第 j 个元素。
当前阶段用于判断的数字从上一个阶段的集合中与[2,3,5,7]组合生成,如此便保证了当前阶段数字的前n-1位是超级质数,再判断后n-1位数是否在上一个阶段的集合中,如果是,即可确定其是当前阶段的超级质数。

举个例子,设abcd是四位数的超级质数,abcde是新生成的数,a,b,c,d,e∈[2,3,4,5],由于已知道abcd是超级质数,那么abcde前n-1位的子串都是质数,现在只需要判断abcde整体是否是质数,和bcde是否是超级质数(其子串是否是质数)。遍历prime[i-1],若bcde == prime[i-1][j]即abcde为本阶段超级质数并保存到当前阶段的集合中。

1.由[2,3,5,7]组合出的两位数质数必然是超级素数。
2.prime[i]集合中保存了该阶段所有的超级质数。
3.i从0开始,prime[i]表示i+1位数的集合,即当i=1时,prime[i]表示2位超级质数的集合。

三、代码

代码如下(示例):

import math

# 判断质数
def isPrime(n) -> bool:
    for i in range(2,int(math.sqrt(n))+1):
        if not n%i:
            # 返回两个参数是为了方便调试
            return False,i
    return True,1


# 判断质数优化版
def isPrimeUp(n) -> bool:
    if n%2 == 0:
        return False,2
    for i in range(3,int(math.sqrt(n))+1,2):
        if n%i == 0:
            return False,i
    return True,1



# 判断其后n-1个字符串是否是超级质数
def substrIsP(n : int,sub : str):
    if str(n)[-len(sub):] == sub:
        return True
    return False



def bfs(pa = [2,3,5,7]): 
    # 每次当前阶段只使用上一个阶段的超级质数,所以使用两个列表交替即可
    Previous = [str(_) for _ in pa]
    present = []
    # 初始化队列
    q = pa.copy()

    # 记录每一个阶段的数量
    numberStages = len(q)
    cut = 0

    # 队列不为空则一直执行
    while q:
        # 成立则进入下一个阶段
        if cut == numberStages:
            cut = 0
            numberStages = len(q)
            # 交换:Previous=present,present = []
            Previous,present = present,[]

        # 取出队列中的元素
        element = q.pop(0)
        cut+=1

        # 对元素进行组合与判断
        for i in pa:
            num = element*10+i

            # 首先num需要是质数,其次它的子串也是质数
            if not isPrime(num)[0]:
                continue
            # 将上一阶段产生的质数用来判断本阶段质数的后n-1子串是否是超级质数
            for j in Previous:
                if substrIsP(num,j):
                    # 成立的数值存入队列与新阶段
                    q.append(num)
                    present.append(str(num))
                    break
    # 最后一个元素必然是最大的超级质数
    else:
        return element


if __name__ == '__main__':
    print(bfs())  # 373

总结

个人感觉不是考察质数的判断,而是对字符串及子串的理解。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
<span style="color:rgb(0,0,0);font-family:'宋体';font-size:large;">要求:将程序代码复制粘贴到一个word文档中上传。</span><span style="color:rgb(0,0,0);font-family:'宋体';font-size:large;">程序如果是正确的,请在word文档中附上最后运行结果的截图。</span><p><span style="color:rgb(0,0,0);font-family:'宋体';font-size:large;">1、必做题</span></p><p> 本题要求实现一个判断素数的简单函数,以及利用该函数判断给定区间整数是否是素数,并按一行5个进行输出的函数。</p><p> 素数:只能被1和自身整除的正整数,1不是素数,2是素数</p><p> 函数接口定义:</p><p> int IsPrime(int x);</p><p> void PrintPrime(int m,int n);</p><p> 其中,函数IsPrime,当x是素数时返回1,否则返回0;函数PrintPrime输出区间[m,n]内的所有素数,按一行5个进行输出,同时要求输出的每列数据左对齐,若在此区间内没有素数,则输出“在此区间不存在素数”的提示信息。</p><p> 要求:main函数中输入两个正整数m和n,调用函数PrintPrime输出结果,函数PrintPrime需调用IsPrime函数来判定区间[m,n]内整数是否为素数。</p><p><br /></p><p>2、选做题</p><p> 有1对兔子,从第3个月开始每个月生一对兔子,生下来的兔子从第3个月开始也是每个月生一对,求第n个月兔子有几对?</p><p> 函数接口定义:</p><p> int rabbit(int n);</p><p> 要求:采用递归调用的方式求解兔子问题,在main函数中输入n,调用rabbit函数求出结果,在main函数中输出结果。</p><p> 输入样例1:</p><p> 6</p><p> 输出样例1:</p><p> 8</p><p> 输入样例2:</p><p> 12</p><p> 输出样例2:</p><p> 144</p><p><br /></p>
05-19

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值