文章目录

  • 题目 1525: 蓝桥杯算法提高VIP-找素数
  • 分析
  • 代码
  • 通过截图
  • 题目 1464: 蓝桥杯基础练习VIP-分解质因数
  • 分析
  • 代码
  • 通过截图


题目 1525: 蓝桥杯算法提高VIP-找素数

时间限制: 1Sec 内存限制: 128MB 提交: 2503 解决: 347
题目描述
给定区间[L,  R]  ,  请计算区间中素数的个数。 


输入
两个数L和R。 



数据规模和约定
2  < =  L  < =  R  < =  2147483647  
R-L  < =  1000000

输出
一行,区间中素数的个数。
样例输入
2 11
样例输出
5

分析

  • 这题不管是用简单的试除法或者简单的埃氏筛,前者容易超时,后者容易爆空间!!!
  • 所以这里的开辟空间,写入状态都有一定技巧。比如我们不要去开b个空间,看看b的范围,这样容易爆空间!!
  • 记得,我们前面说过,埃氏筛适用于10的7次方规模的数据量,但R-L是10的6次方刚好小于这个范围,所以可以用埃氏筛。比如我区间为[10000,20000],我开辟10001个空间(10000到20000有10001个空间),如果10000对应空间0,10001对应空间1,10002对应空间2。发现规律了吗?n对应的空间为n-10000(即n-a)
  • 首先,我们应该知道判断区间[a,b]是不是质数,用试除法只需要到根号b向上取整即可。这就是埃式筛子的范围。前面与埃氏筛的做法一样,乘以相应倍数,标记非素数的状态为false。
  • 我们需要知道我们筛子的数据(2,3,5…)筛区间数据[a,b]的起始点。这里稍微思索一下,不难得出起始点为math.ceil(a/i)*i,这个大家可以稍微举例一下,用归纳法也可以。
  • 筛区间数据这里是导致我刚开始没满分的地方(坑!!!):由于区间数据和筛子的数据可能重复,所以与i重复的一定要定为True(因为前提是i是质数)

代码

import math

a,b = map(int,input().split())
m = int((math.sqrt(b)+1))
flag = [True]* (m+1)
nums = [True]*(b-a+1)
flag[1] = False

# 将筛子做好
for i in range(2,m):
    if flag[i]: # 是质数
        for z in range(i*i,m+1,i):
            flag[z] = False
        for j in range(math.ceil(a/i)*i,b+1,i):
            if j == i:
                nums[i-a] = True
            else:
                nums[j-a] = False


res = 0 # 记录素数个数
for i in nums:
    if i:
        res+=1
print(res)

通过截图

python将列表中的素数和非素数分开 python素数分解_算法

题目 1464: 蓝桥杯基础练习VIP-分解质因数

时间限制: 1Sec 内存限制: 128MB 提交: 3994 解决: 2355
题目描述
求出区间[a,b]中所有整数的质因数分解。 

提示


先筛出所有素数,然后再分解。 

数据规模和约定 







输入
输入两个整数a,b。 

2< =a< =b< =10000

输出
每行输出一个数的分解,形如k=a1*a2*a3...(a1< =a2< =a3...,k也是从小到大的)(具体可看样例) 
样例输入
3 10
样例输出
3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5

分析

  • 小数据试除法去做就好了,不用想太多。
  • 如果是大数据的话,考虑用埃筛法,先筛选出可能的质因数,直接用数和质因数进行操作。
  • 感觉会比较复杂。因为有可能重复,其实在python里面只要找出所有质因数,然后再拼接(用'*'),会好一点。当时没想那么多,就直接完全模拟下来了。所以会看到重复的代码(也有可能是我逻辑比较混乱吧)
  • 首先我们寻找质因数的范围为(2,math.ceil(math.sqrt(n)+1)),这个不过多解释。用flag标记是不是最后一个质因数。
  • 如果a!=i 且a能整除i:证明i是a的其中一个质因数,更新a,判断a是否能再被i整除:如果可以,再打印i并更新a。时刻注意a如果等于i,绝对会是最后一位,因为前面已经被筛掉了,证明a必定是一个质数。
  • 但如果a一开始就是质数或者质因数是质数,那么我们可能筛选不到,所以循环结束没有标记也证明他本身或者最后一位就是质数,打印他,这样在a的更新中,a可能变为浮点数,所以要int取整一下。
  • 代码逻辑不难, 但有点绕,还不是最清晰的,这点也是我可以继续进步的地方,争取以后可以写出更易懂的代码。

代码

import math
def fuc(n):
    print(n,end=
    a = n # 
    while 1:
        flag = 0 # 标记是否是最后一位
        for i in range(2,math.ceil(math.sqrt(n)+1)):
            if a % i == 0 and a != i: # 证明不是最后一位
                print(i,end="*")
                a = a / i # 由于能整除,更新a
                while a % i == 0: # 继续能整除
                    if a == i:
                        print(i)
                        flag = 1
                        break
                    print(i,end="*")
                    a = a/i
            if flag:
                break
            if a == i:
                print(i)
                flag = 1
                break
        if not flag: # 证明最后一个数是素数
            print(int(a)) # 由于除a会变成浮点,所以要转化
        break
        
a,b = map(int,input().split())
for i in range(a,b+1):
    fuc(i)

通过截图

python将列表中的素数和非素数分开 python素数分解_质因数_02


如有错误,敬请指正,欢迎交流,谢谢♪(・ω・)ノ