📌  相关文章
📜  查找给定范围内具有n除数的数字

📅  最后修改于: 2021-05-06 23:09:28             🧑  作者: Mango

给定三个整数a,b,n。您的任务是打印a和b之间的数字个数,包括也有n个除数的数字。如果一个数字有n个除数,包括1和它本身,则称为n除数。
例子:

Input  : a = 1, b = 7, n = 2
Output : 4
There are four numbers with 2 divisors in 
range [1, 7]. The numbers are 2, 3, 5, and 7.

天真的方法:
天真的方法是检查a和b之间的所有数字,以找出n个除数中的多少个,从而找出每个数的每个除数的数量。如果等于n,则为n除数

高效方法:
任何数字都可以以素数分解的形式写成,即数字为x且p1,p2..pm是除以x的素数,因此x = p1 e1 * p2 e2 ….pm em其中e1,e2 … em为质数p1,p2….pm的指数。因此,x的除数为(e1 + 1)*(e2 + 1)… *(em + 1)。
现在第二个观察是质数大于sqrt(x)的指数不能超过1。让我们通过矛盾证明这一点,假设质数P大于sqrt(x)且其质数x的指数E大于1(E> = 2)所以P ^ E sqrt(x)所以P ^ E>(sqrt(x)) E和E> = 2所以P E总是大于x
第三个观察结果是,在x的素数分解中,大于sqrt(x)的质数个数始终小于等于1。这也可以通过上述矛盾类似地证明。

现在解决这个问题
第1步:应用erathesthenes筛网并计算平方根最大为sqrt(b)的素数。

步骤2:从a到b遍历每个数字,并通过将该数字除以质数来计算该数字中每个质数的指数,并使用公式numberofdivisors(x)=(e1 + 1)*(e2 + 1)… 。(em + 1)。

步骤3:如果在数字> 1的基础上将所有小于等于该数平方根的质数相除后,这意味着存在一个大于其平方根的质数,该质数将被除,并且其指数将始终如上文所述。

C++
// C++ program to count numbers with n divisors
#include
using namespace std;
  
// applying sieve of eratosthenes
void sieve(bool primes[], int x)
{
    primes[1] = false;
  
    // if a number is prime mark all its multiples
    // as non prime
    for (int i=2; i*i <= x; i++)
    {
        if (primes[i] == true)
        {
            for (int j=2; j*i <= x; j++)
                primes[i*j] = false;
        }
    }
}
  
// function that returns numbers of number that have
// n divisors in range from a to b. x is sqrt(b) + 1.
int nDivisors(bool primes[], int x, int a, int b, int n)
{
    // result holds number of numbers having n divisors
    int result = 0;
  
    // vector to hold all the prime numbers between 1
    // ans sqrt(b)
    vector  v;
    for (int i = 2; i <= x; i++)
        if (primes[i] == true)
            v.push_back (i);
  
    // Traversing all numbers in given range
    for (int i=a; i<=b; i++)
    {
        // initialising temp as i
        int temp = i;
  
        // total holds the number of divisors of i
        int total = 1;
        int j = 0;
  
        // we need to use that prime numbers that
        // are less than equal to sqrt(temp)
        for (int k = v[j]; k*k <= temp; k = v[++j])
        {
            // holds the exponent of k in prime
            // factorization of i
            int count = 0;
  
            // repeatedly divide temp by k till it is
            // divisible and accordingly increase count
            while (temp%k == 0)
            {
                count++;
                temp = temp/k;
            }
  
            // using the formula  no.of divisors =
            // (e1+1)*(e2+1)....
            total = total*(count+1);
        }
  
        // if temp is not equal to 1 then there is
        // prime number in prime factorization of i
        // greater than sqrt(i)
        if (temp != 1)
            total = total*2;
  
        // if i is a ndvisor number increase result
        if (total == n)
            result++;
    }
    return result;
}
  
// Returns count of numbers in [a..b] having
// n divisors.
int countNDivisors(int a, int b, int n)
{
    int x = sqrt(b) + 1;
  
    // primes[i] = true if i is a prime number
    bool primes[x];
  
    // initialising each number as prime
    memset(primes, true, sizeof(primes));
    sieve(primes, x);
  
    return nDivisors(primes, x, a, b, n);
}
  
// driver code
int main()
{
    int a = 1, b = 7, n = 2;
    cout << countNDivisors(a, b, n);
    return 0;
}


Java
// Java program to count numbers with n divisors 
import java.util.*;
  
class GFG{
// applying sieve of eratosthenes 
static void sieve(boolean[] primes, int x) 
{ 
    primes[1] = true; 
  
    // if a number is prime mark all its multiples 
    // as non prime 
    for (int i=2; i*i <= x; i++) 
    { 
        if (primes[i] == false) 
        { 
            for (int j=2; j*i <= x; j++) 
                primes[i*j] = true; 
        } 
    } 
} 
  
// function that returns numbers of number that have 
// n divisors in range from a to b. x is sqrt(b) + 1. 
static int nDivisors(boolean[] primes, int x, int a, int b, int n) 
{ 
    // result holds number of numbers having n divisors 
    int result = 0; 
  
    // vector to hold all the prime numbers between 1 
    // ans sqrt(b) 
    ArrayList v=new ArrayList(); 
    for (int i = 2; i <= x; i++) 
        if (primes[i] == false) 
            v.add(i); 
      
    // Traversing all numbers in given range 
    for (int i=a; i<=b; i++) 
    { 
        // initialising temp as i 
        int temp = i; 
  
        // total holds the number of divisors of i 
        int total = 1; 
        int j = 0; 
  
        // we need to use that prime numbers that 
        // are less than equal to sqrt(temp)
        for (int k = v.get(j); k*k <= temp; k = v.get(++j))
        { 
            // holds the exponent of k in prime 
            // factorization of i 
            int count = 0; 
  
            // repeatedly divide temp by k till it is 
            // divisible and accordingly increase count 
            while (temp%k == 0) 
            { 
                count++; 
                temp = temp/k; 
            } 
  
            // using the formula no.of divisors = 
            // (e1+1)*(e2+1).... 
            total = total*(count+1);
              
        } 
  
        // if temp is not equal to 1 then there is 
        // prime number in prime factorization of i 
        // greater than sqrt(i) 
        if (temp != 1) 
            total = total*2; 
  
        // if i is a ndvisor number increase result 
        if (total == n) 
            result++; 
    } 
    return result; 
} 
  
// Returns count of numbers in [a..b] having 
// n divisors. 
static int countNDivisors(int a, int b, int n) 
{ 
    int x = (int)Math.sqrt(b) + 1; 
  
    // primes[i] = true if i is a prime number 
    boolean[] primes=new boolean[x+1]; 
  
    // initialising each number as prime 
    sieve(primes, x); 
  
    return nDivisors(primes, x, a, b, n); 
} 
  
// driver code 
public static void main(String[] args) 
{ 
    int a = 1, b = 7, n = 2; 
    System.out.println(countNDivisors(a, b, n)); 
   
} 
}
// This code is contributed by mits


Python3
# Python3 program to count numbers 
# with n divisors 
import math;
  
# applying sieve of eratosthenes 
def sieve(primes, x):
    primes[1] = False;
      
    # if a number is prime mark all 
    # its multiples as non prime
    i = 2;
    while (i * i <= x):
        if (primes[i] == True):
            j = 2;
            while (j * i <= x):
                primes[i * j] = False;
                j += 1;
        i += 1;
  
# function that returns numbers of number 
# that have n divisors in range from a to b.
# x is sqrt(b) + 1. 
def nDivisors(primes, x, a, b, n):
      
    # result holds number of numbers
    # having n divisors 
    result = 0; 
  
    # vector to hold all the prime 
    # numbers between 1 and sqrt(b) 
    v = []; 
    for i in range(2, x + 1): 
        if (primes[i]): 
            v.append(i); 
  
    # Traversing all numbers in given range 
    for i in range(a, b + 1): 
          
        # initialising temp as i 
        temp = i; 
  
        # total holds the number of 
        # divisors of i 
        total = 1; 
        j = 0; 
  
        # we need to use that prime numbers that 
        # are less than equal to sqrt(temp)
        k = v[j];
        while (k * k <= temp):
              
            # holds the exponent of k in prime 
            # factorization of i 
            count = 0; 
  
            # repeatedly divide temp by k till it is 
            # divisible and accordingly increase count 
            while (temp % k == 0):
                count += 1; 
                temp = int(temp / k); 
  
            # using the formula no.of divisors = 
            # (e1+1)*(e2+1).... 
            total = total * (count + 1);
            j += 1;
            k = v[j];
  
        # if temp is not equal to 1 then there is 
        # prime number in prime factorization of i 
        # greater than sqrt(i) 
        if (temp != 1): 
            total = total * 2; 
  
        # if i is a ndivisor number 
        # increase result 
        if (total == n): 
            result += 1; 
    return result; 
  
# Returns count of numbers in [a..b] 
# having n divisors. 
def countNDivisors(a, b, n): 
    x = int(math.sqrt(b) + 1); 
  
    # primes[i] = true if i is a prime number 
    # initialising each number as prime 
    primes = [True] * (x + 1);
    sieve(primes, x); 
  
    return nDivisors(primes, x, a, b, n); 
  
# Driver code 
a = 1;
b = 7;
n = 2; 
print(countNDivisors(a, b, n)); 
  
# This code is contributed by mits


C#
// C# program to count numbers with n divisors 
using System.Collections;
using System;
class GFG{
// applying sieve of eratosthenes 
static void sieve(bool[] primes, int x) 
{ 
    primes[1] = true; 
  
    // if a number is prime mark all its multiples 
    // as non prime 
    for (int i=2; i*i <= x; i++) 
    { 
        if (primes[i] == false) 
        { 
            for (int j=2; j*i <= x; j++) 
                primes[i*j] = true; 
        } 
    } 
} 
  
// function that returns numbers of number that have 
// n divisors in range from a to b. x is sqrt(b) + 1. 
static int nDivisors(bool[] primes, int x, int a, int b, int n) 
{ 
    // result holds number of numbers having n divisors 
    int result = 0; 
  
    // vector to hold all the prime numbers between 1 
    // ans sqrt(b) 
    ArrayList v=new ArrayList(); 
    for (int i = 2; i <= x; i++) 
        if (primes[i] == false) 
            v.Add(i); 
      
    // Traversing all numbers in given range 
    for (int i=a; i<=b; i++) 
    { 
        // initialising temp as i 
        int temp = i; 
  
        // total holds the number of divisors of i 
        int total = 1; 
        int j = 0; 
  
        // we need to use that prime numbers that 
        // are less than equal to sqrt(temp)
        for (int k = (int)v[j]; k*k <= temp; k = (int)v[++j])
        { 
            // holds the exponent of k in prime 
            // factorization of i 
            int count = 0; 
  
            // repeatedly divide temp by k till it is 
            // divisible and accordingly increase count 
            while (temp%k == 0) 
            { 
                count++; 
                temp = temp/k; 
            } 
  
            // using the formula no.of divisors = 
            // (e1+1)*(e2+1).... 
            total = total*(count+1);
              
        } 
  
        // if temp is not equal to 1 then there is 
        // prime number in prime factorization of i 
        // greater than sqrt(i) 
        if (temp != 1) 
            total = total*2; 
  
        // if i is a ndivisor number increase result 
        if (total == n) 
            result++; 
    } 
    return result; 
} 
  
// Returns count of numbers in [a..b] having 
// n divisors. 
static int countNDivisors(int a, int b, int n) 
{ 
    int x = (int)Math.Sqrt(b) + 1; 
  
    // primes[i] = true if i is a prime number 
    bool[] primes=new bool[x+1]; 
  
    // initialising each number as prime 
    sieve(primes, x); 
  
    return nDivisors(primes, x, a, b, n); 
} 
  
// driver code 
public static void Main() 
{ 
    int a = 1, b = 7, n = 2; 
    Console.WriteLine(countNDivisors(a, b, n)); 
   
} 
}
// This code is contributed by mits


PHP


输出:

4