1. 程式人生 > >1007 素數對猜想 Python實現

1007 素數對猜想 Python實現

1007 素數對猜想(20 分)

讓我們定義d​n​​為:d​n​​=p​n+1​​−p​n​​,其中p​i​​是第i個素數。顯然有d​1​​=1,且對於n>1有d​n​​是偶數。“素數對猜想”認為“存在無窮多對相鄰且差為2的素數”。

現給定任意正整數N(<10​5​​),請計算不超過N的滿足猜想的素數對的個數。

輸入格式:

輸入在一行給出正整數N

輸出格式:

在一行中輸出不超過N的滿足猜想的素數對的個數。

輸入樣例:

20

輸出樣例:

4

問題分析:

解題思路很簡單,找出n以內的素數,再尋找相鄰且差為二的素數對

 在實現的過程中,遇到一個十分麻煩的問題,演算法超出時間限制,優化方向當然是素數判斷演算法的優化。所以之後會著重講解素數判斷演算法的優化(需要程式碼的同學直接拉到最後)。

素數判斷演算法一:

直接利用素數定義編寫的演算法:

def prime(a):
    if a<=1:
        return False
    for i in range(2,a-1):
        if a%i==0:
            return False
    return True

利用該演算法輸出100000(十萬)以內素數,程式以及執行時間如下:

程式:

import time
def prime(a):
    if a<=1:
        return False
    for i in range(2,a-1):
        if a%i==0:
            return False
    return True
strat = time.clock()
for i in range(2,100000):
    if prime(i):
        print(i)
end = time.clock()
print(end-strat)

時間:

163.62294357333334

優化一:

在判斷素數時並不需要計算2—n-1的值,實際上只需要計算2—\sqrt{n},第一步優化大家都比較清楚,經過這步優化,減少了\frac{1}{2}的計算量。我們來看看程式,和執行時間。

程式:

import time
import math
def prime(a):
    if a<=1:
        return False
    for i in range(2,int(math.sqrt(a)+1)):
        if a%i==0:
            return False
    return True
strat = time.clock()
for i in range(2,100000):
    if prime(i):
        print(i)
end = time.clock()
print(end-strat)

時間:

59.89916501333333

可以看出時間少了多於一半。

優化二:

我們可以看到,除了2(2是素數)以外的其他偶數都不是素數,除了3(3是素數)以外其他能被3整除的數都不是素數,所以我們每找到一個素數,那麼它的整數倍都不是素數。

程式思路:

建立一個大小為n初始值為1的列表,當找到一個素數時,將它的倍數變為0.

程式:

import time
def prime(n):
    flag = [1]*(n+2)
    p=2
    while(p<=n):
        print(p)
        for i in range(2*p,n+1,p):
            flag[i] = 0
        while 1:
            p += 1
            if(flag[p]==1):
                break
start = time.time()
prime(100000)
end = time.time()
print(end-start)

時間:

59.229109048843384

這種優化時間消耗更少。

用優化一做題會出現超時

優化一,題目程式碼:

def prime(a):
    if a<=1:
        return False
    for i in range(2,int(a**0.5)+1):
        if a%i==0:
            return False
    return True
def sustr(a):
    result = []
    for i in range(a-1):
        if su(i+2)==True:
            result.append(i+2)
    if su(i+2)==True:
        result.append(i+2)
    return result

a = int(input())
b = sustr(a)
num = 0
for i in range(len(b)-1):
    if (b[i+1]-b[i]==2):
        num+=1
print(num)

用優化二做題不會出現超時

優化二,題目程式碼:

def prime(n,result):
    flag = [1]*(n+2)
    p=2
    while(p<=n):
        result.append(p)
        for i in range(2*p,n+1,p):
            flag[i] = 0
        while 1:
            p += 1
            if(flag[p]==1):
                break

a = int(input())
result = []
prime(a,result)
num = 0
for i in range(len(result)-1):
    if (result[i+1]-result[i]==2):
        num+=1
print(num)