解题思路:

首先分析题目:

问题1:数据较大,如果遍历依次判断素数的话,会超时。

解决方法:埃拉托色尼筛选法。原文链接:https://blog.csdn.net/xiaoquantouer/article/details/51817803


问题2:在解题的过程中,我们还会遇到一个问题,就是数组的空间大小问题,如果我们开辟一个大小为(R+1)的数组,然后利用埃拉托色尼筛选法,内存超限。

解决方法:缩小数组空间,此时利用数学知识,将[L,R] 对应到[0,R-L]。

假设L<=p<=R,p为素数,那么在[L,R]之间的所有的p的倍数都是合数(这里至少为2倍)。

我们可以找到找到一个最小倍数k使得k*p在[L,R]之间。k = L/p (向上取整),对应到[0,R-L]之中就是k*p-L,然后k的值不断递加1。对应未转化时去除在[L,R]中的p的倍数。


解决了以上两个问题之后就能解答了。


注意事项:

参考代码:

from math import ceil  
from math import sqrt  
  
def f(l,r):  
    Check = [True]*1000001    #埃拉托色尼筛选法筛选范围
    res = [True]*1000001      #[L,R]转化后的对应空间
    p = 2  
    while p*p <= r:  
        if Check[p]:  
            for i in range(2*p,int(sqrt(r))+1,p):  
                Check[i] = False  
        k = ceil(l/p)    #找到最小倍数,向上取整
        while k * p <= r:  
            if k != 1:  
                res[k*p-l] = False   #去除合数
            k = k + 1  
        p = p + 1  
          
    ans = res[:r-l+1]    #求出转化后空间素数的个数
    print(ans.count(True))  
                      
  
if __name__ == '__main__':  
    l,r = map(int,input().strip().split())  
    f(l,r)


点赞(0)
 

0.0分

2 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论