您的位置:首页 > 编程语言 > C语言/C++

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

2017-05-18 23:44 681 查看

题目

让我们定义 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~40
204
1008
100035
10000205
1000001224

代码

最新代码: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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: