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