Problem C: 第几个素数
Time Limit: 2 Sec Memory Limit: 512 MB
Submit: 1166 Solved: 345
Description
已知2是第一个素数,3是第二个、5是第三个……现在编程序求第k个素数是什么?所求素数均小于10000000。
根据素数定理,不超过x的素数的个数近似于x/ln(x),根据标程测得的数据,不超过10000000的素数不到66万5千个。
建议:分配动态内存。
Input
输入多个整数k,至EOF结束。输入不超过50个整数。
本题共5组测试样例,k的范围和个数满足:
第一组:k<=100,不超过10个;
第二组:k<=1000,不超过10个;
第三组:k<=10000,不超过20个;
第四组:k<=100000,不超过30个;
第五组:k<=1000000,不超过50个。
Output
输出第k个素数。
Sample Input
1
2
3
5
10
100
Sample Output
2
3
5
11
29
541
HINT
当你遇到如下编译错误时,可以考虑分配动态内存。
gcc: Internal error: File size limit exceeded (program as) Please submit a full bug report. See <file:///usr/share/doc/gcc-4.4/README.Bugs> for instructions.
做麻了,听完同学讲后又看的网上的代码:
#include <math.h>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
int main() {
int* ar = (int*)malloc(sizeof(int) * 10000000);
for(int m = 0; m < 10000000; m++)
ar[m] = 0;
int h, i, j, k;
for (i = 2; i <= sqrt(10000000); i++)
if (ar[i] == 0)
for (j = 2 * i; j < 10000000; j += i)
ar[j] = 1;
while (scanf("%d", &k) != EOF) {
h = 0, i = 2;
while (1) {
if (ar[i] == 0)
h++;
if (h == k) {
printf("%d\n", i);
break;
}
i++;
}
}
}
筛法都带出来了,恶心吐了!
欧拉筛法
*如果i是质数,那么就将它与之前的质数(包括它本身)的乘积筛掉。
*如果i是合数,那么就将它与从2到它最小的质因子之间的质数的乘积分别筛掉。
申:
总之意思就是,我们需要在表里筛除合数,而优化算法的过程就是减少一个数被重复筛的次数: 最简单的是筛掉1+2*n的数,再把剩下的数一个个判定;然后是把所有数字都当作筛子,筛掉他们的倍数;
但事实上,把合数当作筛子时,它的倍数已经被他的质因数晒过了,所以只需要用所有质数当筛子筛一遍;——这就是埃氏筛法;埃氏筛法仍有不足;比如面对35的时候,它可以被5和7重复筛一次; 所以我们改良一下这个筛的办法,我们从被筛的数出发,所有的数只用它的最小质因数 筛一次,这样就不会有重复被筛的情况。要实现这个效果也就是(上面的欧拉筛法)——这也就是线性筛法,也叫欧拉筛法
今天准备不足紧张的一匹,然后这些算法网上都有讲的比我好的多的,比如https://blog.csdn.net/tktp_ht/article/details/89310614