所谓孪生素数指的是间隔为2的相邻的素数,他们之间的距离已经近得不能再近了,就像孪生兄弟一样,最小的孪生素数是(3,5),在100以内还有(5,7),(11,13),(17,19),(17,19),(29,31),(41,43),(59,61),(71,73),总计8组。
但随着数字的增大,孪生素数的分布越来越稀疏,寻找起来也变得困难,那会不会在超过某个界限之后就再也没有孪生素数了呢?
孪生素数有无穷多个!这个猜想称为孪生素数猜想,但至今没有被严格证明,但借助计算机我们已经确实可以找到了任意大范围内的所有孪生素数对。
接下来你的任务就是计算不大于n的范围内的孪生素数对的个数!
# include<iostream>
# include<vector>
# include<cmath>
using namespace std;
// ********************************
// 定义孪生素数结构体
// ********************************
struct LsPrime {
int lPrime;
int rPrime;
LsPrime(int l, int r)
{
lPrime = l;
rPrime = r;
}
};
vector<LsPrime> g_lsPrimeVec; // 孪生素数表
vector<int> g_primeVector = {2, 3, 5, 7, 11}; // 素数表
bool IsPrime(int n)
{
for (auto prime : g_primeVector)
{
if (n == prime) {
return true;
}
if (n % prime == 0) {
return false;
}
if (prime > sqrt(n)) {
return true;
}
}
for (int num = g_primeVector.back() + 1; num <= sqrt(n); num++)
{
if (IsPrime(num)) {
g_primeVector.push_back(num);
}
if (n % num == 0) {
return false;
}
}
return true;
}
// ********************************
// 更新孪生素数表
// ********************************
bool UpdateLsPrimeVec(int maxN)
{
int startVar = 2;
// 不需要更新
if (!g_lsPrimeVec.empty())
{
if (g_lsPrimeVec.back().rPrime > maxN) {
return false;
} else {
startVar = g_lsPrimeVec.back().rPrime;
}
}
// 更新孪生素数表
for (int var = startVar; var <= maxN - 2; var ++ )
{
if (IsPrime(var) && IsPrime(var + 2)) {
g_lsPrimeVec.push_back(LsPrime(var, var + 2));
}
}
return true;
}
int GetLsPrimeNum(int maxN)
{
if (UpdateLsPrimeVec(maxN)){
return g_lsPrimeVec.size();
} else {
for (int LsPrimeNum = 0; LsPrimeNum < g_lsPrimeVec.size(); LsPrimeNum ++ )
{
if (g_lsPrimeVec[LsPrimeNum].rPrime > maxN) {
return LsPrimeNum;
}
}
}
}
int main() {
int maxN;
while (cin>>maxN)
{
cout << GetLsPrimeNum(maxN) << ::endl;
}
return 0;
}