我們來看這麼一道問題:
給定乙個範圍n,你需要處理m個某數字是否為質數的詢問(每個數字均在範圍1-n內)n<=10000000,m<=100000首先很容易聯想到使用列舉法來確定題目的整體框架
for( i: 1~m)
else
}
關鍵在於質數判斷部分。
質數的判斷問題我們可以從定義出發。質數,又稱素數,是除了1和它自身以外沒有其他的因子。
bool isprime(int x)
return true;
}
再進一步進行優化,偶數一定不是質數
bool isprime(int x)
return true;
}
但當m,n很大的時侯這種方式的數量級依舊相當大。在一般的機子它不是一秒鐘跑不出結果,它是好幾分鐘都跑不出結果。有沒有更有效率的方法呢?
我們可以考慮使用篩法來進行處理。
根據數學原理:乙個合數總是可以分解成若干個質數的乘積,換個角度去理解,也就是說合數是某個質數的倍數。此時如果把質數的倍數都去掉,那麼剩下的就是質數了。
這樣的篩選方式叫做埃氏篩,也叫埃拉託色尼選篩法,是數學家埃拉託色尼提出的。
**思路:
從質數2開始進行列舉
如果數字是質數,將範圍內所有該數的倍數標記成非質數
繼續向後列舉,直到遍歷完範圍內所有的數字置
**實現:
#include #include using namespace std;
bool isprime[10000005]=;//標記陣列 用來表示數字是否是質數 true-是質數 false-不是質數
void aiprime(int n)
} }}
int main(int argc, char** ar**) else
}return 0;
}
埃氏篩法 素數篩
埃式篩法 給定乙個正整數n n 10 6 問n以內有多少個素數?做法 做法其實很簡單,首先將2到n範圍內的整數寫下來,其中2是最小的素數。將表中所有的2的倍數劃去,表中剩下的最小的數字就是3,他不能被更小的數整除,所以3是素數。再將表中所有的3的倍數劃去 以此類推,如果表中剩餘的最小的數是m,那麼m...
埃氏篩 尤拉篩
對於1 n範圍內素數的查詢,我們常用的二重迴圈暴力演算法的複雜度是o n2 如果利用開根縮小範圍的時間複雜度也無非是在o n nn sqrt n nn 而,這些演算法對於n在105以內都是可以接受的,但是如果需要更大範圍的素數表,這些演算法將顯得力不從心。下面將介紹更加高效的演算法。埃氏篩也叫素數篩...
素數篩 埃氏篩 線性篩 區間篩)
顧名思義,素數篩就是用來篩素數的。1.埃氏篩 o nloglogn 對於一般 不毒瘤 的素數題,埃氏篩就夠了 原理 任何合數都有小於自身的質因數 內容 對於每乙個素數將它的 2 i x i i全部標記為1,使得所有的合數全被標記 不足 合數會被標記素因數次,不夠高效 void prime int x...