(好-----快------)
素數是什麼就不用介紹了吧。。。先介紹判斷素數的方法
先看樸素演算法:
for (i=2;i)if (n%i==0) break
;if (i==n) printf(「n is
prime」);
else printf(「n is not prime」);
(真的好樸素。。)
用時o(n)
(肯定不行啊,吃棗藥丸的。。)
怎麼優化呢?
不難發現,如果a是n的約數,那麼n/a也是n的約數
所以就有以下**:
n2=int(sqrt(n)+0.5);for (i=2;i<=n2;i++) if (n%i==0) break
;if (i>n2) printf(「n is
prime」);
else printf(「n is not prime」);
這個用時o(n^0.5)
一般使用的話這樣其實差不多了。。(其實有乙個更快的只是我不會。。)
進入正題啦!
盡量快的找出1---n之間的所有素數
for(int i=2;i<=n;i++)}if(!flag)
cout
<"";
flag=0
; }
其實也不是很樸素啦。。用了上面介紹的優化,但是速度還是很慢
怎麼優化呢?
對於任意數a,a所有的整數倍都是合數
int flag[2333]; int prime[2333]; intprimes;
for (int i=2;i<=n;i++) flag[i]=0
;for (int i=2;i<=n;i++) for (int j=i*i;j<=n;j+=i) flag[j]=1; //
表示j被標記為合數
for (int i=2;i<=n;i++) if (flag[i]==0) prime[primes++]=i;
有了這個想法,還可以繼續優化
對於質數a,a的所有整數倍都是合數
int flag[2333]; int prime[2333]; intprimes;
for (int i=2;i<=n;i++)
if (flag[i]==0
)
還可以繼續優化嗎?
其實還可以進一步優化,只要每個合數都只被自己能整除的最小的質數標記一次,速度就可以達到線性級別(好快!)
說白了就是每個質數盡可能多的標記合數(也不是很好懂的樣子?)
看**吧:
#includeusingnamespace
std;
int prime[100001
];int f[100001
],primes;
intn;
intmain()
for(int j=0;j//
列舉當前找到的所有素數
}cout
素數個數
for(int i=0;i)
return0;
}
(rp++!)
素數篩法(模板)
質數 在大於1的整數中,如果只包含1和本身這兩個約數,那麼就是素數時間複雜度 o sqrt n static boolean prime int n return true 合數只會被它的最小質因子篩掉 時間複雜度 o n static final int n static int prime ne...
素數篩法 模板
為什麼只遍歷到sqrt n 就夠了?反證法 假設只遍歷2 sqrt n 不能把所有非素數置為false,即遍歷完了2 sqrt n 後,在sqrt n n範圍內仍有乙個非素數k,但isprime k true。證 k在sqrt k 之前一定有乙個素數因子 任何非素數都可以拆成素數的乘積,所以k至少有...
素數篩法(素數篩 線性篩)
求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...