给定一系列限制。对于每个限制,找到可以写为小于或等于限制的最连续的素数之和的素数。
限制的最大可能值为10 ^ 4。
例子:
Input : arr[] = {10, 30}
Output : 5, 17
Explanation : There are two limit values 10 and 30.
Below limit 10, 5 is sum of two consecutive primes,
2 and 3. 5 is the prime number which is sum of largest
chain of consecutive below limit 10.
Below limit 30, 17 is sum of four consecutive primes.
2 + 3 + 5 + 7 = 17
以下是步骤。
- 使用Sundaram筛子查找所有低于最大限制(10 ^ 6)的质数,并将它们存储在质数[]中。
- 为质数[]中的所有质数构造一个前缀和数组prime_sum []
prime_sum [i + 1] = prime_sum [i] +素数[i]。
prime_sum [i]和prime_sum [j]中两个值之间的差表示从索引i到索引j的连续素数之和。 - 遍历两个循环,从i(0到极限)的外循环和从j(0到i)的内循环
- 对于每个i,内部循环遍历(0到i),我们检查当前连续质数( consSum = prime_sum [i] – prime_sum [j])的当前和是否是质数(我们使用二进制搜索在prime []中搜索consSum )。
- 如果consSum是素数,那么如果当前长度大于当前结果的长度,我们将更新结果。
以下是上述步骤的实现。
C++
// C++ program to find Longest Sum of consecutive
// primes
#include
using namespace std;
const int MAX = 10000;
// utility function for sieve of sundaram
void sieveSundaram(vector &primes)
{
// In general Sieve of Sundaram, produces primes smaller
// than (2*x + 2) for a number given number x. Since
// we want primes smaller than MAX, we reduce MAX to half
// This array is used to separate numbers of the form
// i+j+2ij from others where 1 <= i <= j
bool marked[MAX/2 + 1] = {0};
// Main logic of Sundaram. Mark all numbers which
// do not generate prime number by doing 2*i+1
for (int i=1; i<=(sqrt(MAX)-1)/2; i++)
for (int j=(i*(i+1))<<1; j<=MAX/2; j=j+2*i+1)
marked[j] = true;
// Since 2 is a prime number
primes.push_back(2);
// Print other primes. Remaining primes are of the
// form 2*i + 1 such that marked[i] is false.
for (int i=1; i<=MAX/2; i++)
if (marked[i] == false)
primes.push_back(2*i + 1);
}
// function find the prime number which can be written
// as the sum of the most consecutive primes
int LSCPUtil(int limit, vector &prime, long long int sum_prime[])
{
// To store maximum length of consecutive primes that can
// sum to a limit
int max_length = -1;
// The prime number (or result) that can be reprsented as
// sum of maximum number of primes.
int prime_number = -1;
// Conisder all lengths of consecutive primes below limit.
for (int i=0; prime[i]<=limit; i++)
{
for (int j=0; j limit)
break;
// sum_prime[i]-sum_prime[j] is prime number or not
long long int consSum = sum_prime[i] - sum_prime[j];
// Check if sum of current length of consecutives is
// prime or not.
if (binary_search(prime.begin(), prime.end(), consSum))
{
// update the length and prime number
if (max_length < i-j+1)
{
max_length = i-j+1;
prime_number = consSum;
}
}
}
}
return prime_number;
}
// Returns the prime number that can written as sum
// of longest chain of consecutive primes.
void LSCP(int arr[], int n)
{
// Store prime number in vector
vector primes;
sieveSundaram(primes);
long long int sum_prime[primes.size() + 1];
// Calculate sum of prime numbers and store them
// in sum_prime array. sum_prime[i] stores sum of
// prime numbers from primes[0] to primes[i-1]
sum_prime[0] = 0;
for (int i = 1 ; i <= primes.size(); i++)
sum_prime[i] = primes[i-1] + sum_prime[i-1];
// Process all queries one by one
for (int i=0; i
Java
// Java program to find longest sum
// of consecutive primes
import java.util.*;
class GFG{
static int MAX = 10000;
// Store prime number in vector
static ArrayList
C#
// C# program to find longest sum
// of consecutive primes
using System;
using System.Collections;
class GFG{
static int MAX = 10000;
// Store prime number in vector
static ArrayList primes = new ArrayList();
// Utility function for sieve of sundaram
static void sieveSundaram()
{
// In general Sieve of Sundaram,
// produces primes smaller than
// (2*x + 2) for a number given
// number x. Since we want primes
// smaller than MAX, we reduce MAX
// to half. This array is used to
// separate numbers of the form
// i+j+2ij from others where 1 <= i <= j
bool []marked = new bool[MAX / 2 + 1];
Array.Fill(marked, false);
// Main logic of Sundaram. Mark
// all numbers which do not
// generate prime number by
// doing 2*i+1
for(int i = 1;
i <= (Math.Sqrt(MAX) - 1) / 2; i++)
for(int j = (i * (i + 1)) << 1;
j <= MAX / 2;
j = j + 2 * i + 1)
marked[j] = true;
// Since 2 is a prime number
primes.Add(2);
// Print other primes. Remaining
// primes are of the form
// 2*i + 1 such that marked[i] is false.
for(int i = 1; i <= MAX / 2; i++)
if (marked[i] == false)
primes.Add(2 * i + 1);
}
// Function find the prime number
// which can be written as the
// sum of the most consecutive primes
static int LSCPUtil(int limit, long []sum_prime)
{
// To store maximum length of
// consecutive primes that can
// sum to a limit
int max_length = -1;
// The prime number (or result)
// that can be reprsented as
// sum of maximum number of primes.
int prime_number = -1;
// Conisder all lengths of
// consecutive primes below limit.
for(int i = 0; (int)primes[i] <= limit; i++)
{
for(int j = 0; j < i; j++)
{
// If we cross the limit, then
// break the loop
if (sum_prime[i] - sum_prime[j] >
limit)
break;
// sum_prime[i]-sum_prime[j] is
// prime number or not
long consSum = sum_prime[i] -
sum_prime[j];
int[] prime = (int[])primes.ToArray(typeof(int));
// Check if sum of current length
// of consecutives is prime or not.
if (Array.BinarySearch(prime,
(int)consSum) >= 0)
{
// Update the length and prime number
if (max_length < i - j + 1)
{
max_length = i - j + 1;
prime_number = (int)consSum;
}
}
}
}
return prime_number;
}
// Returns the prime number that
// can written as sum of longest
// chain of consecutive primes.
static void LSCP(int []arr, int n)
{
sieveSundaram();
long []sum_prime = new long[primes.Count + 1];
// Calculate sum of prime numbers
// and store them in sum_prime
// array. sum_prime[i] stores sum
// of prime numbers from
// primes[0] to primes[i-1]
sum_prime[0] = 0;
for(int i = 1; i <= primes.Count; i++)
sum_prime[i] = (int)primes[i - 1] +
sum_prime[i - 1];
// Process all queries one by one
for(int i = 0; i < n; i++)
Console.Write(LSCPUtil(
arr[i], sum_prime) + " ");
}
// Driver code
public static void Main(string []arg)
{
int []arr = { 10, 30, 40, 50, 1000 };
int n = arr.Length;
LSCP(arr, n);
}
}
// This code is contributed by rutvik_56
输出:
5 17 17 41 953