Vue知識點總結(16)——具名插槽(超級詳細)
阿新 • • 發佈:2021-01-09
Eratosthenes 篩法和線性篩法
Eratosthenes 篩法
很早就聽他們提到過素數篩法的概念但是一直沒有去查,直到一個月前寫到一個關於素數的揹包問題才發現不會篩法只能面對T的慘痛現實。今天早晨發現自己又雙叒叕忘記怎麼敲了……………。
Eratosthenes 篩法原理
基本原理:其實就是從2開始不斷的篩去素數的倍數,這是由於每一個合數都能寫為幾個素數的冪的乘積。然後呢,如果比某個數小的所有素數都不能篩掉這個數的話這個數其實就是一個素數。基本原理很簡單現在來看看具體如何實現。
實現步驟
1.兩個陣列,is_prime用來標記素數便於後續的篩法prime用來記錄素數
3.進入for迴圈從2開始篩,如果某一數沒有被比它小的數篩去則下一次篩去它的倍數。
4.其中又一個小優化,篩素數的時候是從i*i開始篩的,因為如果i乘j(j<i),那麼這個數會被j提前篩去。
程式碼
#define N 10005
bool is_prime[N];//記錄是否是素數
int prime[N];//儲存素數
int ans=0;//記錄素數個數
int PRIME()
{
memset(is_prime, true,sizeof(is_prime));//現將所有的是認為是素數便於之後篩選
is_prime[0]=0; //取消0,1的標記
is_prime[1]=0;
for(int i=2;i<=N;i++)//從2開始取消2的倍數的標記
{
if(is_prime[i])//如果是素數則可以篩掉他的倍數
{
prime[ans++]=i;
for(int j=i*i;j<=N;j=j+i)//可以跳過i-i*i中的數,因為它會被小於i的數篩掉
{
is_prime[j]=false;
}
}
}
return 0;
}
線性篩
原理
直接上盜的圖
線性篩比起前面的埃氏篩好處就是沒有重複的篩去同一個合數.
原理:這個篩法所有的合數只能被它最小的素數約數篩去,比如6被2篩去而不是3.
大家看程式碼和上圖可以發現每一次迴圈對應這上圖的一行,以4乘2為例,這一行不會有4乘3那是因為4%2為0直接跳出。12只能被2篩去。
程式碼
#define N 10005
bool is_prime[N];//記錄是否是素數
int prime[N];//儲存素數
int ans=0;//記錄素數個數
int PRIME() {
memset(is_prime, true, sizeof(is_prime));//現將所有的是認為是素數便於之後篩選
is_prime[0] = false;//取消0,1的標記
is_prime[1] = false;
for (int i = 2; i < N; i++) {
if (is_prime[i])//標記素數
prime[ans++] = i;
for (int j = 0; j < ans && i * prime[j] < N; j = j + 1) {
is_prime[i * prime[j]] = false;
if (i % prime[j] == 0)//這裡很有意思,說明只用被篩去數約數中最小的數篩去,相當於只篩一次
break;
}
}
return 0;
}