质数
首先是最简单的质数判定,基本质数判定就是判断其是否能够被小于他的数整除,但是如果我们不加思考的直接从小到大除一遍,未免有点太暴力了,但是我们稍加思考一下,基本上其实对于一个数只需要求到这个数的平方根即可。故我们可以将原本的O(n)复杂度的问题,降低到O(sqrt(n))复杂度。
例题6.7 素数判定
直接按照思路写代码就行了。
from math import sqrt
while 1:
try:
a=int(input())
flag=0
roundary=int(sqrt(a))+1
#一定注意两个小值:
if(a<2):
flag=1
print("no")
for i in range(2,roundary):
if(a%i==0):
print("no")
flag=1
break
if(flag==0):print("yes")
except:
break
一定注意1,2这两个较小值
下面我们再看一个算法,我们称之为素数枚举法。算法来自于以下题目,我们需要求得一个最大值范围内所有的素数,我们当然可以选择使用判断素数加上一个for循环来进行循环暴力求解,但是这样的话真的就很暴力,很有可能过不去时间复杂度。所以我们选择使用一个“动态规划”的思想(我记得是叫动态规划,个人感觉动态规划就是拿空间换时间,欢迎指教)
例题6.8素数
这道题就是我们说的一个叫做素数筛法的一种算法,这道题细节还是蛮多的,总的来讲就是将整个范围内的素数进行一个统一的筛选,然后从2开始没筛选出一个素数就把他的倍数都标记为非素数,这样就自然而然的筛选出对应的全部素数了,这个对筛选大量素数效果极佳。还有一些细节列出代码在代码注释中细讲。
JudgePrime=[];prime=[]
def init(MaxIter):
for i in range(MaxIter):
JudgePrime.append(1)
JudgePrime[0]=0
JudgePrime[1]=0
iteration=0
while 1:
if iteration>=MaxIter:
break
if(not JudgePrime[iteration]):
iteration += 1
continue
prime.append(iteration)
step=iteration*iteration
temp=iteration
#这一步至关重要这里我们并没有从2*i开始标记而是从i*i开始标记,
#原因既是我们当我们选用这种素数筛法进行素数求解的过程中,
#2*i肯定在其他素数筛选过程中被标记了,
#所以我们直接从i*i开始
while 1:
if (step>=MaxIter):
break
JudgePrime[step]=0
step+=temp
iteration += 1
Numeber=int(input())
init(Numeber)
flag=0
for i in prime:
if (i%10==1):
flag=1
print(i,end=" ")
else:
print(-1)
我们并没有从2 * i开始标记而是从i*i开始标记,原因既是我们当我们选用这种素数筛法进行素数求解的过程中,2 * i肯定在其他素数筛选过程中被标记了,所以我们直接从i * i开始进行标记
习题6.6 K-th Prime Number
这道题也既是素数筛法的一个变种,主要就是试出来那个max的最大值,然后就从你找到的素数列表里面按需取一下就行
JudgePrime=[];prime=[]
def init(MaxIter=100000):
for i in range(MaxIter):
JudgePrime.append(1)
JudgePrime[0]=0
JudgePrime[1]=0
iteration=0
while 1:
if iteration>=MaxIter:
break
if(not JudgePrime[iteration]):
iteration += 1
continue
prime.append(iteration)
step=iteration*iteration
temp=iteration
#这一步至关重要这里我们并没有从2*i开始标记而是从i*i开始标记,
#原因既是我们当我们选用这种素数筛法进行素数求解的过程中,
#2*i肯定在其他素数筛选过程中被标记了,
#所以我们直接从i*i开始
while 1:
if (step>=MaxIter):
break
JudgePrime[step]=0
step+=temp
iteration += 1
while 1:
try:
Numeber=int(input())
init()
print(prime[Numeber-1])
except:
break