码迷,mamicode.com
首页 > 其他好文 > 详细

大素数筛子

时间:2016-08-01 22:55:45      阅读:347      评论:0      收藏:0      [点我收藏+]

标签:

题目地址:http://acm.fafu.edu.cn/problem.php?id=1011

Description:

The problem is very simple,your job is just to calculate the sum of primes from the first prime to the Nth prime.

Input:

The input consists multiple cases. Each line contains a N(1<=N<=1000000).

Output:

For each N,output the result of this problem that describe before.

Sample Input:

1

3

5

Sample Output:

2

10

28

 

 

题目意思是说输入一个N,计算从第1个素数到第N个素数的和。注意看题目,N最大可能达到100万。也就是说测试数据有可能让你计算从第1个素数到第100万个素数的和。这题的难点在于如何快速筛选出素数。如果我们用枚举法(或普通的方法),那必定会超时。这里,我要介绍一个大素数筛子(专门筛选素数)。

 

我们知道2,5,7...这些都是素数。而素数的倍数一定不是素数,那么我们只要将已经判断过的素数的倍速删去即可。举个例子:2,3,4,5,6,7,8,9,10,11,12,131415,16,17,18,19,20

(1)判断2是否素数;是;将2的倍数删去后剩:

2,3,5,7,9,11,13,15,17,19

(2)判断3是否素数;是;将3的倍数删去后剩:

2,3,5,7,11,13,17,19

(3)判断5是否素数;是;将5的倍数删去后剩........以此类推。

 

那么代码该如何实现呢?假设我们要求第1个到第100个素数可以定义一个isPrime数组来标记是否为素数。再确定数组大小之前,我们要先判断一下第100个素数可能有多大。这里我们先假设为400

 

技术分享
for(i = 2; i <= 20; ++i)//这里i<=sqrt(400)即400的开方
    if(isPrime[i])
        for(j = 2*i; j <= 400; j+=i)    // i+i 就是 i 的倍数
            isPrime[j] = false;            //素数的倍数置零
View Code

 

标记完,isPrime[i]等于1的,就是素数,而且该素数就是其下标。接下来就可以获取素数了。

 

技术分享
for(i = 2,k=1; i <= 400; ++i)
    if(map[i])     prime[k++] = i;
        //从下标1开始存放第一个素数
View Code

 

 

if(map[i]) prime[k++] = i;//从下标1开始存放第一个素数

剩下的工作就轻松多了!整体代码如下:

技术分享
#include<cstdio>
#include<cstring>
#define N 1000000
#define maxn 16000000
bool map[maxn];
__int64 prime[N+5]={0};
__int64 sum[N+5]={0};
int main(void)
{
    memset(map,true,sizeof(map));
    int i,j,n,k=1;
    for(i = 2; i <= 4000; ++i)
        if(map[i])
            for(j = 2*i; j < maxn; j+=i)//将素数的倍数置零
                map[j] = false;

    for(i = 2,j = 1; i <= maxn && j <= N; ++i)
        if(map[i]) 
        {
            prime[k++] = i;//从下标1开始存放第一个素数
            sum[j] = sum[j-1]+prime[j]; ++j;//sum[k]为第1~k个素数的和
        }
    while(scanf("%d",&n) != EOF)
        printf("%I64d\n",sum[n]);

    return 0;
}
View Code

这个代码中,我用map数组表示状态(即isPrime数组的功能),用prime数组来存放素数。sum数组来存结果。如sum[10]的值为第1个素数到第10个素数的和。

大素数筛子

标签:

原文地址:http://www.cnblogs.com/Muia/p/5727472.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!