给定一个正整数N ,任务是查找小于或等于N的质数计数,该计数可以表示为两个质数之和。
例子:
Input: N = 6
Output: 1
Explanation:
5 is the only prime number over the range [1, 6] that can be represented as sum of 2 prime numbers i.e., 5 = 2 + 3, where 2, 3 and 5 are all primes.
Therefore, the count is 2.
Input: N = 14
Output: 3
天真的方法:解决给定问题的最简单方法是考虑范围[1,N]内的所有可能对(i,j),如果i和j是质数并且(i + j)在范围[1] ,N],然后增加素数的计数。检查所有可能的对之后,打印获得的总计数值。
时间复杂度: O(N 3 )
辅助空间: O(1)
高效的方法:还可以基于以下观察来优化上述方法:
- 除2外,所有素数均为奇数
- 无法将质数(奇数)表示为两个奇数质数之和,因此两个质数之一应为2 。
- 因此,要使质数X为两个质数之和, X – 2也必须是质数。
请按照以下步骤解决问题:
- 初始化一个数组,假设其大小为10 5的prime [] ,并使用Eratosthenes筛子填充所有质数直到10 5。
- 初始化大小为(N +1)的辅助数组dp [] ,其中dp [i]是小于或等于i的质数的计数,可以表示为2个质数的总和。
- 使用变量i遍历[2,N]范围,并执行以下步骤:
- 将dp [i – 1]的值更新为dp [i – 1]和dp [i]的总和。
- 检查prime [i]和prime [i – 2]是否为true ,然后将dp [i]的值增加1 。
- 完成上述步骤后,打印dp [N]的值作为结果计数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to store all prime numbers
// up to N using Sieve of Eratosthenes
void SieveOfEratosthenes(
int n, bool prime[])
{
// Set 0 and 1 as non-prime
prime[0] = 0;
prime[1] = 0;
for (int p = 2; p * p <= n; p++) {
// If p is prime
if (prime[p] == true) {
// Set all multiples
// of p as non-prime
for (int i = p * p;
i <= n; i += p) {
prime[i] = false;
}
}
}
}
// Function to count prime numbers
// up to N that can be represented
// as the sum of two prime numbers
void countPrime(int n)
{
// Stores all the prime numbers
bool prime[n + 1];
memset(prime, true, sizeof(prime));
// Update the prime array
SieveOfEratosthenes(n, prime);
// Create a dp array of size n + 1
int dp[n + 1];
memset(dp, 0, sizeof(dp));
// Update dp[1] = 0
dp[1] = 0;
// Iterate over the range [2, N]
for (int i = 2; i <= n; i++) {
// Add the previous count value
dp[i] += dp[i - 1];
// Increment dp[i] by 1 if i
// and (i - 2) are both prime
if (prime[i] == 1
&& prime[i - 2] == 1) {
dp[i]++;
}
}
// Print the result
cout << dp[n];
}
// Driver Code
int main()
{
int N = 6;
countPrime(N);
return 0;
}
输出:
1
时间复杂度: O(N * log(log(N)))
辅助空间: O(N)