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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.