题目
让我们定义
d
n
d_{n}
dn 为:
d
n
=
p
n
+
1
−
p
n
d_{n} =p_{n+1} −p_{n}
dn=pn+1−pn ,其中
p
i
p_{i}
pi是第i
个素数。显然有
d
1
=
1
d_{1}=1
d1=1,且对于
n
>
1
n>1
n>1有
d
n
d_n
dn是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。现给定任意正整数
N
(
<
1
0
5
)
N(<10^5)
N(<105),请计算不超过
N
N
N的满足猜想的素数对的个数。
输入格式
输入在一行给出正整数N
。
输出格式
在一行中输出不超过N
的满足猜想的素数对的个数。
输入样例
20
输出样例
4
代码
#include <stdio.h>
#include <math.h>
#include <malloc.h>
#define true 1
#define false 0
typedef struct list{
int *a;
size_t length; //线性表长度
size_t size; //线性表大小
} list;
//线性表初始化
void init(list * list){
list->a = (int *) malloc(sizeof(int)*10);
if(!list->a)
exit(-1);
list->length = 0;
list->size = 10;
}
//线性表扩展
void expand(list * list){
list->a = (int *) realloc(list->a, sizeof(int)*(list->size+10));
if(!list->a)
exit(-1);
list->size += 10;
}
//在尾部插入元素,时间复杂度o(1)
void push(list * list, int n){
if(list->length == list->size-1)
expand(list);
list->a[list->length] = n;
list->length++;
}
//素数判定,时间复杂度o(√n),判定素数只需要检测√n个元素即可
_Bool isprime(int n){
int k;
k = (int)sqrt((double)n);
_Bool result = true;
for(int i = 2; i <= k; i++){
if(n%i == 0){
result = false;
break;
}
}
return result;
}
int main(void){
int n, count = 0;
list list;
scanf("%d",&n);
init(&list);
push(&list, 2);
for(int i = 3; i <= n ; i+=2){
if(isprime(i))
push(&list, i);
}
for(int i = 1; i <= list.length; i++){
if(list.a[i] - list.a[i-1]==2)
count++;
}
printf("%d\n",count);
return 0;
}
小结
本题主要是对素数的一个判定,判定并不需要检测
n
−
1
n-1
n−1个元素,只需要检测是否能被
n
\sqrt{n}
n个元素整除即可。使用线性表是为了更好的管理内存,即将元素存储进线性表中。事实上,由于素数肯定是从小到大递增的,可以直接在遍历3~n
的过程中计算
d
i
d_i
di,并进行统计。