题目
让我们定义
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
i
i 个素数。显然有
d
1
=
1
{d_1} = 1
d1=1,且对于
n
>
1
n>1
n>1 有
d
n
{d_n}
dn 是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2
的素数”。
现给定任意正整数N
(
<
10
5
)
(<10^5)
(<105),请计算不超过N
的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N
。
输出格式:
在一行中输出不超过N
的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
思路&总结
思路(2020-4-9 01:09:00):
1、将N之前的所有素数依次列出来,数一下相邻两个素数差值是
2
的总共有多少对。
2、老规矩,素数表使用数组保存,方法类似键值对。
*优化点也就是主要的时间消耗点在于素数判断。百度到直接构造素数表的方法应该较快,也就是在一张表中直接踢掉非素数,剩下的就是素数了,时间复杂度是 o ( n ) o(n) o(n)。答案1是用的循环遍历判断有木有因数从而判断是否为素数,时间复杂度是 o ( n 3 2 ) o({n^{\frac{3}{2}}}) o(n23)。答案2.等下想想写不写构造素数表再决定答案2存不存在。
总结(2020-4-9 01:58:11)
1、素数判断循环上限可以使用
sqrt(n)
提高判断效率。
2、当需要用到连续的多个素数时,可以用构造素数表的方式提高时间效率。
3、使用sqrt(n)
需要#include <math.h>
。
4、memset(void *str, int c, size_t n)
将str
中当前位置到后面的n
个字节填充c
。可用来做数组初始化.
5、解释二void *memset(void *s, int v, size_t n)
包含在<string.h>
头文件中,可以用它对一片内存空间逐字节进行初始化。 这里s
可以是数组名,也可以是指向某一内在空间的指针;v
为要填充的值;n
为要填充的字节数;
6、根据https://blog.csdn.net/u011426016/article/details/86559895 的指示,也只能用来处理某些赋值,最好是char
类型,int
类型容易出错,计组学的好的可以研究一下这个博客,就是涉及到数据结构的物理存储和计算机存储的源码补码反码这些问题了,用来给char
赋初始值就完全某门题。
7、根据百度百科 这个,也讲的很仔细,学习。
8、使用memset()
需要#include <string.h>
。
答案1(2020-4-9 01:58:27)
#include <iostream>
#include <math.h>
using namespace std;
int isPrimeNumber(int k)
{
if (k<=1) return 0;
int maxDivisor = (int)sqrt(k);
for (int i = 2; i <= maxDivisor ; i++)
if(k % i == 0)
return 0;
return 1;
}
int main(int argc, char *argv[]) {
int n;
cin >> n;
int primeNumber[n] = {0};
for (int i = 2; i <= n ; i++)
if(isPrimeNumber(i)==1) primeNumber[i] = 1;
int countCouple = 0;
for (int i = 5; i <= n ; i++)
if(primeNumber[i] == 1 && primeNumber[i-2] == 1 )
countCouple ++;
cout << countCouple;
return 0;
}
答案2(2020-4-9 02:19:42)
测试点5运行时间由16ms缩减为4ms
#include <iostream>
#include <math.h>
using namespace std;
int main(int argc, char *argv[]) {
int n;
cin >> n;
int primeNumber[n+1] = {0};
//createPrimeTable
for (int i = 2; i < n ; i++)
{
if(primeNumber[i]==0)
{
int j = 2;
for(j = 2 ; j * i <= n ; j++)
primeNumber[j*i] = 2;//not prime;
}
}
//count PrimeCouple
int countCouple = 0;
for (int i = 5; i <= n ; i++)
if(primeNumber[i] == 0 && primeNumber[i-2] == 0 )
countCouple ++;
cout << countCouple;
return 0;
}