100000th prime algorithm by baihacker ....
Attention:是第第第100,000個,不是100,000以內!!!!
貌似這個數很大啊~這是金山的筆試題目,怎麼算?說出大致思想也成,拜謝了!遍歷肯定是不行的吧?雖然我答案就是用寫的遍歷-_-""!
#include
#include
unsigned int s[100000] = {2};
unsigned int s_i = 1;
inline int is_sushu(unsigned int n)
{
int m = sqrt(n)+1;
for (int i=0; s[i]<=m; i++) {
if (i==s_i)
return 1;
if (n%s[i]==0)
return 0;
}
return 1;
}
int main()
{
for (int i=3; s_i!=100000; i+=2)
if (is_sushu(i))
s[s_i++] = i;
printf("%d/n", s[99999]);
}
答案:1299709.
一個素數爲素數的條件是不能被它之前的任何素數給整除,事實上,還有一個條件,假設n爲合數,則存在除一和它自身的兩個數a,b,使得a×b=n,兩個數之中必定有一個小於根號n,一個大於根號n,故此,可以得出結論,如果一個數n不能被小於根號n的所有輸整除,則此數是素數。算法如下,不過是Java的。希望能滿足你的要求。
Java code
public static void main(String[] args)
{
int len = 100000;
int[] arr = new int[len];
arr[0] = 2;
int m = 3;
int i = 1;
while(i < len){
boolean isLeap = true;
for(int j = 0; j < i && arr[j] < Math.sqrt(m) + 1; j++){
if(m % arr[j] == 0){
isLeap = false;
break;
}
}
if(isLeap){
arr[i++] = m;
}
m += 2;
}
System.out.println(arr[len - 1]);
}
兩種方法:
1.就是暴力,篩選出第十萬個
已經知道:
1百以內:25 97
1千以內:168 997
1萬以內:1229 9973
10萬以內:9592 99991
100萬以內:78498 999983
1000萬以內:664579 9999991
所以,大概在200萬以內篩選就OK了.
(篩選1億以內的素數大概是不超過10秒(我的計算機), 100萬差不多是瞬間)
2.二分枚舉
記函數search(n)的功能爲計算n以內的素數的個數
那麼
int l = 1, r = max;
while (l <= r)
{
int mid = (l + r) >> 1;
if (search(mid) >= 100000) r = mid - 1;
else l = mid + 1;
}
l爲所求.
現在問題的關鍵在於高效計算search(n),可以用容斥原理...
//暫時只給第一種的實現,大家可以測試一下在自己電腦上跑多少時間.
#include
#include
using namespace std;
const int MAX_PRIME = 2000000;
int PrimeTable[6000000];
int IsPrime[MAX_PRIME+1];
int PrimeCnt = 0;
void get_prime()
{
memset(IsPrime, 1, sizeof(IsPrime));
IsPrime[0] = IsPrime[1] = 0;
for (int i = 2 ; i < MAX_PRIME; i++)
if (IsPrime[i])
{
for (long long j = (PrimeTable[PrimeCnt++] = i) * (long long)i; j < MAX_PRIME; j += i)
IsPrime[j] = 0;
}
}
int main()
{
get_prime();
printf("%d/n", PrimeTable[99999]);
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.