您将得到两个数字a和b(1 <= a,b <= 10 ^ 8)和n。任务是找到a和b之间的所有数字,包括正好是n个不同的素数。该解决方案的设计方式应像竞争编程中那样有效地处理针对a和b的不同值的多个查询。
例子:
Input : a = 1, b = 10, n = 2
Output : 2
// Only 6 = 2*3 and 10 = 2*5 have exactly two
// distinct prime factors
Input : a = 1, b = 100, n = 3
Output: 8
// only 30 = 2*3*5, 42 = 2*3*7, 60 = 2*2*3*5, 66 = 2*3*11,
// 70 = 2*5*7, 78 = 2*3*13, 84 = 2*2*3*7 and 90 = 2*3*3*5
// have exactly three distinct prime factors
这个问题基本上是分段筛的应用。众所周知,一个数字的所有素数总是小于或等于数字的平方根,即; sqrt(n)。因此,我们生成所有小于或等于10 ^ 8的质数,并将它们存储在数组中。现在,使用此分段筛子,我们检查从a到b的每个数字是否有n个素数。
C++
// C++ program to find numbers with exactly n distinct
// prime factor numbers from a to b
#include
using namespace std;
// Stores all primes less than and equals to sqrt(10^8) = 10000
vector primes;
// Generate all prime numbers less than or equals to sqrt(10^8)
// = 10000 using sieve of sundaram
void segmentedSieve()
{
int n = 10000; // Square root of 10^8
// In general Sieve of Sundaram, produces primes smaller
// than (2*x + 2) for a number given number x.
// Since we want primes smaller than n=10^4, we reduce
// n to half
int nNew = (n-2)/2;
// This array is used to separate numbers of the form
// i+j+2ij from others where 1 <= i <= j
bool marked[nNew + 1];
// Initalize all elements as not marked
memset(marked, false, sizeof(marked));
// Main logic of Sundaram. Mark all numbers of the
// form i + j + 2ij as true where 1 <= i <= j
for (int i=1; i<=nNew; i++)
for (int j=i; (i + j + 2*i*j) <= nNew; j++)
marked[i + j + 2*i*j] = true;
// Since 2 is a prime number
primes.push_back(2);
// Remaining primes are of the form 2*i + 1 such that
// marked[i] is false.
for (int i=1; i<=nNew; i++)
if (marked[i] == false)
primes.push_back(2*i+1);
}
// Function to count all numbers from a to b having exactly
// n prime factors
int Nfactors(int a, int b, int n)
{
segmentedSieve();
// result --> all numbers between a and b having
// exactly n prime factors
int result = 0;
// check for each number
for (int i=a; i<=b; i++)
{
// tmp --> stores square root of current number because
// all prime factors are always less than and
// equal to square root of given number
// copy --> it holds the copy of current number
int tmp = sqrt(i), copy = i;
// count --> it counts the number of distinct prime
// factors of number
int count = 0;
// check divisibility of 'copy' with each prime less
// than 'tmp' and divide it until it is divisible by
// current prime factor
for (int j=0; primes[j]<=tmp; j++)
{
if (copy%primes[j]==0)
{
// increment count for distinct prime
count++;
while (copy%primes[j]==0)
copy = copy/primes[j];
}
}
// if number is completely divisible then at last
// 'copy' will be 1 else 'copy' will be prime, so
// increment count by one
if (copy != 1)
count++;
// if number has exactly n distinct primes then
// increment result by one
if (count==n)
result++;
}
return result;
}
// Driver program to run the case
int main()
{
int a = 1, b = 100, n = 3;
cout << Nfactors(a, b, n);
return 0;
}
Java
// Java program to find numbers with exactly n distinct
// prime factor numbers from a to b
import java.util.*;
class GFG
{
// Stores all primes less than and
// equals to sqrt(10^8) = 10000
static ArrayList primes = new ArrayList();
// Generate all prime numbers less
// than or equals to sqrt(10^8)
// = 10000 using sieve of sundaram
static void segmentedSieve()
{
int n = 10000; // Square root of 10^8
// In general Sieve of Sundaram,
// produces primes smaller
// than (2*x + 2) for a number
// given number x. Since we want
// primes smaller than n=10^4,
// we reduce n to half
int nNew = (n - 2)/2;
// This array is used to separate
// numbers of the form i+j+2ij
// from others where 1 <= i <= j
boolean[] marked=new boolean[nNew + 1];
// Main logic of Sundaram. Mark all
// numbers of the form i + j + 2ij
// as true where 1 <= i <= j
for (int i = 1; i <= nNew; i++)
for (int j = i; (i + j + 2 * i * j) <= nNew; j++)
marked[i + j + 2 * i * j] = true;
// Since 2 is a prime number
primes.add(2);
// Remaining primes are of the form 2*i + 1 such that
// marked[i] is false.
for (int i = 1; i <= nNew; i++)
if (marked[i] == false)
primes.add(2 * i + 1);
}
// Function to count all numbers from a to b having exactly
// n prime factors
static int Nfactors(int a, int b, int n)
{
segmentedSieve();
// result --> all numbers between a and b having
// exactly n prime factors
int result = 0;
// check for each number
for (int i = a; i <= b; i++)
{
// tmp --> stores square root of current number because
// all prime factors are always less than and
// equal to square root of given number
// copy --> it holds the copy of current number
int tmp = (int)Math.sqrt(i), copy = i;
// count --> it counts the number of distinct prime
// factors of number
int count = 0;
// check divisibility of 'copy' with each prime less
// than 'tmp' and divide it until it is divisible by
// current prime factor
for (int j = 0; primes.get(j) <= tmp; j++)
{
if (copy % primes.get(j) == 0)
{
// increment count for distinct prime
count++;
while (copy % primes.get(j) == 0)
copy = copy/primes.get(j);
}
}
// if number is completely divisible then at last
// 'copy' will be 1 else 'copy' will be prime, so
// increment count by one
if (copy != 1)
count++;
// if number has exactly n distinct primes then
// increment result by one
if (count == n)
result++;
}
return result;
}
// Driver code
public static void main (String[] args)
{
int a = 1, b = 100, n = 3;
System.out.println(Nfactors(a, b, n));
}
}
// This code is contributed by chandan_jnu
Python3
# Python3 program to find numbers with
# exactly n distinct prime factor numbers
# from a to b
import math
# Stores all primes less than and
# equals to sqrt(10^8) = 10000
primes = [];
# Generate all prime numbers less than
# or equals to sqrt(10^8) = 10000
# using sieve of sundaram
def segmentedSieve():
n = 10000; # Square root of 10^8
# In general Sieve of Sundaram, produces
# primes smaller than (2*x + 2) for a
# given number x. Since we want primes
# smaller than n=10^4, we reduce n to half
nNew = int((n - 2) / 2);
# This array is used to separate
# numbers of the form i+j+2ij
# from others where 1 <= i <= j
marked = [False] * (nNew + 1);
# Main logic of Sundaram. Mark all
# numbers of the form i + j + 2ij
# as true where 1 <= i <= j
for i in range(1, nNew + 1):
j = i;
while ((i + j + 2 * i * j) <= nNew):
marked[i + j + 2 * i * j] = True;
j += 1;
# Since 2 is a prime number
primes.append(2);
# Remaining primes are of the
# form 2*i + 1 such that
# marked[i] is false.
for i in range(1, nNew + 1):
if (marked[i] == False):
primes.append(2 * i + 1);
# Function to count all numbers
# from a to b having exactly n
# prime factors
def Nfactors(a, b, n):
segmentedSieve();
# result --> all numbers between
# a and b having exactly n prime
# factors
result = 0;
# check for each number
for i in range(a, b + 1):
# tmp --> stores square root of
# current number because all prime
# factors are always less than and
# equal to square root of given number
# copy --> it holds the copy of
# current number
tmp = math.sqrt(i);
copy = i;
# count --> it counts the number of
# distinct prime factors of number
count = 0;
# check divisibility of 'copy' with
# each prime less than 'tmp' and
# divide it until it is divisible
# by current prime factor
j = 0;
while (primes[j] <= tmp):
if (copy % primes[j] == 0):
# increment count for
# distinct prime
count += 1;
while (copy % primes[j] == 0):
copy = (copy // primes[j]);
j += 1;
# if number is completely divisible
# then at last 'copy' will be 1 else
# 'copy' will be prime, so increment
# count by one
if (copy != 1):
count += 1;
# if number has exactly n distinct
# primes then increment result by one
if (count == n):
result += 1;
return result;
# Driver Code
a = 1;
b = 100;
n = 3;
print(Nfactors(a, b, n));
# This code is contributed
# by chandan_jnu
C#
// C# program to find numbers with exactly n
// distinct prime factor numbers from a to b
using System;
using System.Collections;
class GFG
{
// Stores all primes less than and
// equals to sqrt(10^8) = 10000
static ArrayList primes = new ArrayList();
// Generate all prime numbers less
// than or equals to sqrt(10^8)
// = 10000 using sieve of sundaram
static void segmentedSieve()
{
int n = 10000; // Square root of 10^8
// In general Sieve of Sundaram, produces
// primes smaller than (2*x + 2) for a number
// given number x. Since we want primes
// smaller than n=10^4, we reduce n to half
int nNew = (n - 2) / 2;
// This array is used to separate
// numbers of the form i+j+2ij
// from others where 1 <= i <= j
bool[] marked = new bool[nNew + 1];
// Main logic of Sundaram. Mark all
// numbers of the form i + j + 2ij
// as true where 1 <= i <= j
for (int i = 1; i <= nNew; i++)
for (int j = i;
(i + j + 2 * i * j) <= nNew; j++)
marked[i + j + 2 * i * j] = true;
// Since 2 is a prime number
primes.Add(2);
// Remaining primes are of the form
// 2*i + 1 such that marked[i] is false.
for (int i = 1; i <= nNew; i++)
if (marked[i] == false)
primes.Add(2 * i + 1);
}
// Function to count all numbers from
// a to b having exactly n prime factors
static int Nfactors(int a, int b, int n)
{
segmentedSieve();
// result --> all numbers between a and b
// having exactly n prime factors
int result = 0;
// check for each number
for (int i = a; i <= b; i++)
{
// tmp --> stores square root of current
// number because all prime factors are
// always less than and equal to square
// root of given number
// copy --> it holds the copy of current number
int tmp = (int)Math.Sqrt(i), copy = i;
// count --> it counts the number of
// distinct prime factors of number
int count = 0;
// check divisibility of 'copy' with each
// prime less than 'tmp' and divide it until
// it is divisible by current prime factor
for (int j = 0; (int)primes[j] <= tmp; j++)
{
if (copy % (int)primes[j] == 0)
{
// increment count for distinct prime
count++;
while (copy % (int)primes[j] == 0)
copy = copy / (int)primes[j];
}
}
// if number is completely divisible then
// at last 'copy' will be 1 else 'copy'
// will be prime, so increment count by one
if (copy != 1)
count++;
// if number has exactly n distinct
// primes then increment result by one
if (count == n)
result++;
}
return result;
}
// Driver code
public static void Main()
{
int a = 1, b = 100, n = 3;
Console.WriteLine(Nfactors(a, b, n));
}
}
// This code is contributed by mits
PHP
all numbers between a and b
// having exactly n prime factors
$result = 0;
// check for each number
for ($i = $a; $i <= $b; $i++)
{
// tmp --> stores square root of current
// number because all prime factors are
// always less than and equal to square
// root of given number
// copy --> it holds the copy of current number
$tmp = sqrt($i);
$copy = $i;
// count --> it counts the number of
// distinct prime factors of number
$count = 0;
// check divisibility of 'copy' with each
// prime less than 'tmp' and divide it until
// it is divisible by current prime factor
for ($j = 0; $primes[$j] <= $tmp; $j++)
{
if ($copy % $primes[$j] == 0)
{
// increment count for distinct prime
$count++;
while ($copy % $primes[$j] == 0)
$copy = (int)($copy / $primes[$j]);
}
}
// if number is completely divisible then
// at last 'copy' will be 1 else 'copy'
// will be prime, so increment count by one
if ($copy != 1)
$count++;
// if number has exactly n distinct primes
// then increment result by one
if ($count == $n)
$result++;
}
return $result;
}
// Driver Code
$a = 1;
$b = 100;
$n = 3;
print(Nfactors($a, $b, $n));
// This code is contributed by chandan_jnu
?>
输出:
8
如果您有其他方法可以解决此问题,请分享评论。