让我们定义 d
n 为:d
n = p
n+1 - p
n,其中 p
i 是第i个素数。显然有 d
1=1 且对于n>1有 d
n 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N (< 105),请计算不超过N的满足猜想的素数对的个数。
输入格式:每个测试输入包含1个测试用例,给出正整数N。
输出格式:每个测试用例的输出占一行,不超过N的满足猜想的素数对的个数。
输入样例:20输出样例:
4
我做做个题的思路是:
用筛选法,先筛选出题目中要求的数据内(1-100,00)素数存入一个数组Prime_num. 然后找到输入N的位置,
对于N之前的素数进行遍历,求出满足要求的素数对的个数
其实我觉得可以再优化一下,先输入N,然后再去构建那个指数表(只用1-N即可),这样可以节省空间、时间
#include <stdio.h>
#include <math.h>
#define RANGE 100001
int main(int argc, const char* argv[])
{
int Prime_num[RANGE];
int i, j;
// 赋值,之后进行筛选法求素数
for(i = 1; i < RANGE; i++)
Prime_num[i] = i;
// 从2开始到sqrt(RANGE)作为因子
for(i = 2; i < sqrt(RANGE); i++)
for(j = i + 1; j <= RANGE; j++)// 筛选因子之后的数
if(Prime_num[i] != 0 && Prime_num[j] != 0)
if(Prime_num[j] % Prime_num[i] == 0)
Prime_num[j] = 0; // 一旦被整除,就挖去
int cnt = 0;
for(i = 0; i < RANGE; i++)
if(Prime_num[i] != 0)
{
Prime_num[cnt] = Prime_num[i];
cnt ++;
}
// 检查数组中的质数是否正确
// {
// for(i = 0; i <= cnt; i++)
// {
// printf("%5d", Prime_num[i]);
// if(i % 10 == 0)
// printf("\n");
// }
// }
int N, max, max_loc;
scanf("%d", &N);
// // 找出输入数的位置及最大的质数
// for(i = 1; i < cnt; i++)
// /*
// 此处的if判断有问题,因为数组里最大的质数(9973)比100000小
// 所以,输入N = 100000时,就找不到那个质数及其位置
// */
// if(Prime_num[i] > N)
// {
// max = Prime_num[i-1];
// max_loc = i - 1;
// break;
// }
max = Prime_num[cnt - 1];
max_loc = cnt - 1;
for(i = 1; i < cnt; i++)
if(N < Prime_num[i])
{
max = Prime_num[i - 1];
max_loc = i - 1;
break;
}
/*
有个检验方法代码是否考虑到边界的方法:
因为最大的质数为9973,所以输入比9973大的数字,结果都是一致的
*/
cnt = 0;
for(i = 1; i < max_loc; i++)
{
if(Prime_num[i+1] - Prime_num[i] == 2)
cnt ++;
}
printf("%d\n", cnt);
return 0;
}