PAT Basic 1007. 素数对猜想 (20) (C语言实现)

来源:互联网 发布:ppt2010软件官方下载 编辑:程序博客网 时间:2024/05/29 16:46

题目

让我们定义 d_n 为:d_n = p_{n+1} - p_n,其中 p_i 是第i个素数。显然有 d_1=1 且对于n>1有 d_n 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。

现给定任意正整数N (< 10^5),请计算不超过N的满足猜想的素数对的个数。

输入格式:每个测试输入包含1个测试用例,给出正整数N。

输出格式:每个测试用例的输出占一行,不超过N的满足猜想的素数对的个数。

输入样例
20

输出样例
4

思路

大致思路:验证[1-N]每一个数n是否为素数,如果n和n-2同时为素数,则找到一对“孪生素数”

验证某一个数n为素数时,只需验证n能否被小于sqrt(n)的素数整除即可,题目限制最大数为10^5,其平方根约为320(不到),320以内的素数可以粗略计算应该能保证在100个之内,估算方法[1]可以使用320/ln(320)=55.4(实际是65个),当然这是粗略估算的粗略估算,具体要在运行时用100 000验证一下没有段错误来保证。

结论:使用长度为100的数组记录前一百个素数,即可检验100 000以内所有数是否是素数。

记录孪生素数也可以只用三个标记数来记录连续三个数n, n + 1, n + 2的素数情况。

参考:[1] Wiki: Prime number theorem

代码实现:

初始化:100个素数里初始化便写入前两个2,3,从4开始验证,这样不影响边界情况(N=5之前没有孪生素数),避免了2这样没有更小的素数可供验证的情况,并且进入循环即可开始验证孪生素数。

结果参考:

N孪生素数对数1~402041008100035100002051000001224

代码

最新代码:github,欢迎交流 ^_^

#include <stdio.h>int main(){    int N;    scanf("%d", &N);    /* record three successive numbers if they are prime numbers, start from 2, 3, 4 */    int iPrimeMinus2 = 1, iPrimeMinus1 = 1, iPrime;    /* record the prime numbers before sqrt(10^5) */    int primes[100] = {2, 3};    int paircount = 0;    int primecount = 2;    for (int i = 4; i <= N; i++)    {        iPrime = 1;        /* test if i is a prime number */        for(int j = 0; primes[j] * primes[j] <= i; j++) if(i % primes[j] == 0)        {            iPrime = 0;            break;        }        /* i is a prime number */        if(iPrime == 1)        {            if(primecount < 100)    primes[primecount++] = i;            if(iPrimeMinus2 == 1)   paircount++;    /* a prime pair found */        }        /* change the flags */        iPrimeMinus2 = iPrimeMinus1;        iPrimeMinus1 = iPrime;    }    printf("%d", paircount);    return 0;}
阅读全文
1 0