给定两个整数L和R ,任务是找到在[L,R]范围内的质数总数的计数,该范围的数字之和也是质数。
例子:
Input: L = 1, R = 10
Output: 4
Explanation:
Prime numbers in the range L = 1 to R = 10 are {2, 3, 5, 7}.
Their sum of digits is {2, 3, 5, 7}.
Since all the numbers are prime, hence the answer to the query is 4.
Input: L = 5, R = 20
Output: 3
Explanation:
Prime numbers in the range L = 5 to R = 20 are {5, 7, 11, 13, 17, 19}.1
Their sum of digits is {5, 7, 2, 4, 8, 10}.
Only {5, 7, 2} are prime, hence the answer to the query is 3.
天真的方法:天真的方法是对[L,R]范围内的每个数字进行迭代,并检查该数字是否为质数。如果数字为质数,请找到其数字的总和,然后再次检查该总和是否为质数。如果总和为素数,则在[L,R]范围内增加当前元素的计数器。
时间复杂度: O((R – L)* log(log P))其中P是[L,R]范围内的质数。
高效方法:
- 使用Eratosthenes筛子将所有从1到10 6的质数存储在数组中。
- 创建另一个数组,该数组将存储从1到10 6的所有数字的数字的和是否为质数。
- 现在,计算一个前缀数组以存储计数,直到每个值超出限制为止。
- 一旦有了前缀数组, prefix [R] – prefix [L-1]的值将给出给定范围内为素数且其和也为素数的元素计数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
int maxN = 1000000;
// Create an array for storing primes
int arr[1000001];
// Create a prefix array that will
// contain whether sum is prime or not
int prefix[1000001];
// Function to find primes in the range
// and check whether the sum of digits
// of a prime number is prime or not
void findPrimes()
{
// Initialise Prime array arr[]
for (int i = 1; i <= maxN; i++)
arr[i] = 1;
// Since 0 and 1 are not prime
// numbers we mark them as '0'
arr[0] = 0, arr[1] = 0;
// Using Sieve Of Eratosthenes
for (int i = 2; i * i <= maxN; i++) {
// if the number is prime
if (arr[i] == 1) {
// Mark all the multiples
// of i starting from sqaure
// of i with '0' ie. composite
for (int j = i * i;
j <= maxN; j += i) {
//'0' represents not prime
arr[j] = 0;
}
}
}
// Initialise a sum variable as 0
int sum = 0;
prefix[0] = 0;
for (int i = 1; i <= maxN; i++) {
// Check if the number is prime
if (arr[i] == 1) {
// A temporary variable to
// store the number
int temp = i;
sum = 0;
// Loop to calculate the
// sum of digits
while (temp > 0) {
int x = temp % 10;
sum += x;
temp = temp / 10;
// Check if the sum of prime
// number is prime
if (arr[sum] == 1) {
// if prime mark 1
prefix[i] = 1;
}
else {
// If not prime mark 0
prefix[i] = 0;
}
}
}
}
// computing prefix array
for (int i = 1; i <= maxN; i++) {
prefix[i]
+= prefix[i - 1];
}
}
// Function to count the prime numbers
// in the range [L, R]
void countNumbersInRange(int l, int r)
{
// Function Call to find primes
findPrimes();
int result = prefix[r]
- prefix[l - 1];
// Print the result
cout << result << endl;
}
// Driver Code
int main()
{
// Input range
int l, r;
l = 5, r = 20;
// Function Call
countNumbersInRange(l, r);
return 0;
}
Java
// Java program for the above approach
class GFG{
static int maxN = 1000000;
// Create an array for storing primes
static int []arr = new int[1000001];
// Create a prefix array that will
// contain whether sum is prime or not
static int []prefix = new int[1000001];
// Function to find primes in the range
// and check whether the sum of digits
// of a prime number is prime or not
static void findPrimes()
{
// Initialise Prime array arr[]
for (int i = 1; i <= maxN; i++)
arr[i] = 1;
// Since 0 and 1 are not prime
// numbers we mark them as '0'
arr[0] = 0;
arr[1] = 0;
// Using Sieve Of Eratosthenes
for (int i = 2; i * i <= maxN; i++)
{
// if the number is prime
if (arr[i] == 1)
{
// Mark all the multiples
// of i starting from sqaure
// of i with '0' ie. composite
for (int j = i * i;
j <= maxN; j += i)
{
//'0' represents not prime
arr[j] = 0;
}
}
}
// Initialise a sum variable as 0
int sum = 0;
prefix[0] = 0;
for (int i = 1; i <= maxN; i++)
{
// Check if the number is prime
if (arr[i] == 1)
{
// A temporary variable to
// store the number
int temp = i;
sum = 0;
// Loop to calculate the
// sum of digits
while (temp > 0)
{
int x = temp % 10;
sum += x;
temp = temp / 10;
// Check if the sum of prime
// number is prime
if (arr[sum] == 1)
{
// if prime mark 1
prefix[i] = 1;
}
else
{
// If not prime mark 0
prefix[i] = 0;
}
}
}
}
// computing prefix array
for (int i = 1; i <= maxN; i++)
{
prefix[i] += prefix[i - 1];
}
}
// Function to count the prime numbers
// in the range [L, R]
static void countNumbersInRange(int l, int r)
{
// Function Call to find primes
findPrimes();
int result = prefix[r] - prefix[l - 1];
// Print the result
System.out.print(result + "\n");
}
// Driver Code
public static void main(String[] args)
{
// Input range
int l, r;
l = 5;
r = 20;
// Function Call
countNumbersInRange(l, r);
}
}
// This code is contributed by sapnasingh4991
Python3
# Python3 program for the above approach
maxN = 1000000
# Create an array for storing primes
arr = [0] * (1000001)
# Create a prefix array that will
# contain whether sum is prime or not
prefix = [0] * (1000001)
# Function to find primes in the range
# and check whether the sum of digits
# of a prime number is prime or not
def findPrimes():
# Initialise Prime array arr[]
for i in range(1, maxN + 1):
arr[i] = 1
# Since 0 and 1 are not prime
# numbers we mark them as '0'
arr[0] = 0
arr[1] = 0
# Using Sieve Of Eratosthenes
i = 2
while i * i <= maxN:
# If the number is prime
if (arr[i] == 1):
# Mark all the multiples
# of i starting from sqaure
# of i with '0' ie. composite
for j in range(i * i, maxN, i):
# '0' represents not prime
arr[j] = 0
i += 1
# Initialise a sum variable as 0
sum = 0
prefix[0] = 0
for i in range(1, maxN + 1):
# Check if the number is prime
if (arr[i] == 1):
# A temporary variable to
# store the number
temp = i
sum = 0
# Loop to calculate the
# sum of digits
while (temp > 0):
x = temp % 10
sum += x
temp = temp // 10
# Check if the sum of prime
# number is prime
if (arr[sum] == 1):
# If prime mark 1
prefix[i] = 1
else:
# If not prime mark 0
prefix[i] = 0
# Computing prefix array
for i in range(1, maxN + 1):
prefix[i] += prefix[i - 1]
# Function to count the prime numbers
# in the range [L, R]
def countNumbersInRange(l, r):
# Function call to find primes
findPrimes()
result = (prefix[r] - prefix[l - 1])
# Print the result
print(result)
# Driver Code
if __name__ == "__main__":
# Input range
l = 5
r = 20
# Function call
countNumbersInRange(l, r)
# This code is contributed by chitranayal
C#
// C# program for the above approach
using System;
class GFG{
static int maxN = 1000000;
// Create an array for storing primes
static int []arr = new int[1000001];
// Create a prefix array that will
// contain whether sum is prime or not
static int []prefix = new int[1000001];
// Function to find primes in the range
// and check whether the sum of digits
// of a prime number is prime or not
static void findPrimes()
{
// Initialise Prime array arr[]
for (int i = 1; i <= maxN; i++)
arr[i] = 1;
// Since 0 and 1 are not prime
// numbers we mark them as '0'
arr[0] = 0;
arr[1] = 0;
// Using Sieve Of Eratosthenes
for (int i = 2; i * i <= maxN; i++)
{
// if the number is prime
if (arr[i] == 1)
{
// Mark all the multiples
// of i starting from sqaure
// of i with '0' ie. composite
for (int j = i * i;
j <= maxN; j += i)
{
//'0' represents not prime
arr[j] = 0;
}
}
}
// Initialise a sum variable as 0
int sum = 0;
prefix[0] = 0;
for (int i = 1; i <= maxN; i++)
{
// Check if the number is prime
if (arr[i] == 1)
{
// A temporary variable to
// store the number
int temp = i;
sum = 0;
// Loop to calculate the
// sum of digits
while (temp > 0)
{
int x = temp % 10;
sum += x;
temp = temp / 10;
// Check if the sum of prime
// number is prime
if (arr[sum] == 1)
{
// if prime mark 1
prefix[i] = 1;
}
else
{
// If not prime mark 0
prefix[i] = 0;
}
}
}
}
// computing prefix array
for (int i = 1; i <= maxN; i++)
{
prefix[i] += prefix[i - 1];
}
}
// Function to count the prime numbers
// in the range [L, R]
static void countNumbersInRange(int l, int r)
{
// Function Call to find primes
findPrimes();
int result = prefix[r] - prefix[l - 1];
// Print the result
Console.Write(result + "\n");
}
// Driver Code
public static void Main()
{
// Input range
int l, r;
l = 5;
r = 20;
// Function Call
countNumbersInRange(l, r);
}
}
// This code is contributed by Code_Mech
Javascript
3
时间复杂度: O(N *(log(log)N))
辅助空间: O(N)