让我们定义dn为:dn=pn+1−pn,其中pi是第i个素数。显然有d1=1,且对于n>1有dn
是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。
现给定任意正整数N(<10^5),请计算不超过N的满足猜想的素数对的个数。
输入格式:
输入在一行给出正整数N。
输出格式:
在一行中输出不超过N的满足猜想的素数对的个数。
输入样例:
20
输出样例:
4
运行超时的原因主要在于求素数的算法不够快,参考了网上的算法,发现用筛法求素数速度非常快,所以就采用了。用计算n%2到n%n-1的方法求素数肯定超时。这里的速度提上去了其余部分就很简单了。
有关筛法求素数的方法可以自行百度学习,最好是掌握这个算法,我也简单学习了这个算法,比如判断n以内的素数,用n+1个bool类型的数组或其他容器来存,将偶数置为false(均可被2整除),奇数置为true(有可能是素数),再从3遍历这个数组,如果i是true,那么将这个数的倍数全部置为false(第一次遇到的奇数i肯定是素数,那么他后面的倍数自然就不是素数了,因为他们可以整除i),关于代码中j如何递增去覆盖后面的数从而进一步提升速度还有更深度的讨论,可以自行学习。关于为什么是sqrt(n)参考合数的有关理论,总是分布在sqrt(n)两侧。最后遍历一遍bool数组,将素数放到新的容器,再判断相差为 2的素数,用计数器计数,最后输出计数器的值即可。
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
vector<int>re;
void Prime(int n)
{
bool* prime = new bool[n+1];
prime[2]=true;
for (int i = 3; i < n+1; i++)
if (i % 2)
prime[i] = true;
else
prime[i] = false;
for (int i = 2; i <= sqrt(n); i++)
if (prime[i])
for (int j = i+i; j < n+1; j += i)
prime[j] = false;
for (int i = 2; i < n+1; i++)
if (prime[i])
re.push_back(i);
}
int main()
{
int n;
cin >> n;
Prime(n);
int count = 0;
for (int i = 1; i < re.size(); i++)
if (re[i] - re[i - 1] == 2)
count++;
cout << count;
return 0;
}