从a到b正好n个不同的素数

给你两个数字a和b(1<=a,b<=10^8)和n。任务是找到a和b之间的所有数字,包括正好有n个不同的素数因子。该解决方案的设计应能有效地处理针对不同a和b值的多个查询,就像在竞争性编程中一样。 例如:

null
Input  : a = 1, b = 10, n = 2Output : 2// Only 6 = 2*3 and 10 = 2*5 have exactly two // distinct prime factorsInput : a = 1, b = 100, n = 3Output: 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<bits/stdc++.h>
using namespace std;
// Stores all primes less than and equals to sqrt(10^8) = 10000
vector < int > 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];
// Initialize 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<Integer> primes = new ArrayList<Integer>();
// 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

<?php
// PHP program to find numbers with exactly n
// distinct prime factor numbers from a to b
// Stores all primes less than and equals
// to sqrt(10^8) = 10000
$primes = array ();
// Generate all prime numbers less than or
// equals to sqrt(10^8) = 10000 using
// sieve of sundaram
function segmentedSieve()
{
global $primes ;
$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 = array_fill (0, $nNew + 1, false);
// Main logic of Sundaram. Mark all numbers of the
// form i + j + 2ij as true where 1 <= i <= j
for ( $i = 1; $i <= $nNew ; $i ++)
for ( $j = $i ;
( $i + $j + 2 * $i * $j ) <= $nNew ; $j ++)
$marked [ $i + $j + 2 * $i * $j ] = true;
// Since 2 is a prime number
array_push ( $primes , 2);
// Remaining primes are of the form 2*i + 1
// such that marked[i] is false.
for ( $i = 1; $i <= $nNew ; $i ++)
if ( $marked [ $i ] == false)
array_push ( $primes , 2 * $i + 1);
}
// Function to count all numbers from a to b
// having exactly n prime factors
function Nfactors( $a , $b , $n )
{
global $primes ;
segmentedSieve();
// result --> 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
?>


Javascript

<script>
// JavaScript program to find numbers with exactly n
// distinct prime factor numbers from a to b
// Stores all primes less than and
// equals to sqrt(10^8) = 10000
let primes = [];
// Generate all prime numbers less
// than or equals to sqrt(10^8)
// = 10000 using sieve of sundaram
function segmentedSieve()
{
let 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
let nNew = parseInt((n - 2) / 2, 10);
// This array is used to separate
// numbers of the form i+j+2ij
// from others where 1 <= i <= j
let marked = new Array(nNew + 1);
marked.fill( false );
// Main logic of Sundaram. Mark all
// numbers of the form i + j + 2ij
// as true where 1 <= i <= j
for (let i = 1; i <= nNew; i++)
for (let j = i;
(i + j + 2 * i * j) <= nNew; j++)
marked[i + j + 2 * i * j] = true ;
// Since 2 is a prime number
primes.push(2);
// Remaining primes are of the form
// 2*i + 1 such that marked[i] is false.
for (let i = 1; i <= nNew; i++)
if (marked[i] == false )
primes.push(2 * i + 1);
}
// Function to count all numbers from
// a to b having exactly n prime factors
function Nfactors(a, b, n)
{
segmentedSieve();
// result --> all numbers between a and b
// having exactly n prime factors
let result = 0;
// check for each number
for (let 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
let tmp = parseInt(Math.sqrt(i), 10), copy = i;
// count --> it counts the number of
// distinct prime factors of number
let count = 0;
// check divisibility of 'copy' with each
// prime less than 'tmp' and divide it until
// it is divisible by current prime factor
for (let j = 0; primes[j] <= tmp; j++)
{
if (copy % primes[j] == 0)
{
// increment count for distinct prime
count++;
while (copy % primes[j] == 0)
copy = parseInt(copy / primes[j], 10);
}
}
// 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;
}
let a = 1, b = 100, n = 3;
document.write(Nfactors(a, b, n));
</script>


输出:

8

如果你有其他方法来解决这个问题,请在评论中分享。 本文由 沙申克·米什拉(古卢) .如果你喜欢GeekSforgek,并想贡献自己的力量,你也可以使用 写极客。组织 或者把你的文章寄去评论-team@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写下评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享