📜  等值数字

📅  最后修改于: 2021-05-04 21:35:01             🧑  作者: Mango

如果n的素数分解中的位数(包括幂)与n中的位数相同,则将数字n称为Equidigital。

例如16是一个等值数字,因为其素数分解为2 ^ 4,并且其素数分解具有总计两位数(2和4),与16中的位数总数相同。
再举一个例子,128不是等值数字,因为其素数分解为2 ^ 7,并且总共有2位数字(2和7),而number有3位数字。

所有素数均为Equidigital。

给定数字n,任务是打印所有等于n的Equidigital数字。
例子:

Input: n = 10 
Output: 1, 2, 3, 5, 7, 10.
Note that 4, 6, 8 and 9 are not Equidigital.

Input :  n = 20
Output :  1 2 3 5 7 10 11 13 14 15 16 17 19

方法(打印所有小于或等于n的Equidigital数字)

  1. 使用Sundaram筛网计算所有质数,直至10 ^ 6。
  2. 在n中查找位数。
  3. 找到n的所有素数,并对每个素数p进行跟随。
    • 在p中查找位数。
    • 计算除以n的p的最高幂。
    • 查找以上两个的总和。
  4. 比较两个总和。如果两个总和相同,则返回true。

以下是上述想法的实现。

C++
// C++ Program to find Equidigital Numbers till n
#include
using namespace std;
const int MAX  = 10000;
  
// Array to store all prime less than and equal to MAX.
vector  primes;
  
// Utility function for sieve of sundaram
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[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);
}
  
// Returns true if n is a Equidigital number, else
// false.
bool isEquidigital(int n)
{
    if (n == 1)
        return true;
  
    // Count digits in original number
    int original_no = n;
    int sumDigits = 0;
    while (original_no > 0)
    {
        sumDigits++;
        original_no = original_no/10;
    }
  
  
    // Count all digits in prime factors of n
    // pDigit is going to hold this value.
    int pDigit = 0 , count_exp = 0, p;
    for (int i = 0; primes[i] <= n/2; i++)
    {
        // Count powers of p in n
        while (n % primes[i] == 0)
        {
            // If primes[i] is a prime factor,
            p = primes[i];
            n = n/p;
  
            // Count the power of prime factors
            count_exp++;
        }
  
        // Add its digits to pDigit.
        while (p > 0)
        {
            pDigit++;
            p = p / 10;
        }
  
        // Add digits of power of prime factors to pDigit.
        while (count_exp > 1)
        {
            pDigit++;
            count_exp = count_exp / 10;
        }
    }
  
    // If n!=1 then one prime factor still to be
    // summed up;
    if (n != 1)
    {
        while (n > 0)
        {
            pDigit++;
            n = n/10;
        }
    }
  
    // If digits in prime factors and
    // digits in original number are same, then
    // return true. Else return false.
    return (pDigit == sumDigits);
}
  
// Driver code
int main()
{
    // Finding all prime numbers before limit. These
    // numbers are used to find prime factors.
    sieveSundaram();
  
    cout << "Printing first few Equidigital Numbers"
         " using isEquidigital()\n";
    for (int i=1; i<20; i++)
        if (isEquidigital(i))
            cout << i << " ";
    return 0;
}


Java
// Java program to find Equidigital Numbers till n
  
import java.util.Vector;
import static java.lang.Math.sqrt;
  
class GFG 
{
    static final int MAX = 10000;
    static Vector primes = new Vector(MAX+1);
      
    // 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
        boolean marked[] = new boolean[MAX/2 + 1];
       
        // 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.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);
    }
       
    // Returns true if n is a Equidigital number, else
    // false.
    static boolean isEquidigital(int n)
    {
        if (n == 1)
            return true;
       
        // Count digits in original number
        int original_no = n;
        int sumDigits = 0;
        while (original_no > 0)
        {
            sumDigits++;
            original_no = original_no/10;
        }
       
       
        // Count all digits in prime factors of n
        // pDigit is going to hold this value.
        int pDigit = 0 , count_exp = 0, p = 0;
        for (int i = 0; primes.elementAt(i) <= n/2; i++)
        {
            // Count powers of p in n
            while (n % primes.elementAt(i) == 0)
            {
                // If primes[i] is a prime factor,
                p = primes.elementAt(i);
                n = n/p;
       
                // Count the power of prime factors
                count_exp++;
            }
       
            // Add its digits to pDigit.
            while (p > 0)
            {
                pDigit++;
                p = p / 10;
            }
       
            // Add digits of power of prime factors to pDigit.
            while (count_exp > 1)
            {
                pDigit++;
                count_exp = count_exp / 10;
            }
        }
       
        // If n!=1 then one prime factor still to be
        // summed up;
        if (n != 1)
        {
            while (n > 0)
            {
                pDigit++;
                n = n/10;
            }
        }
       
        // If digits in prime factors and
        // digits in original number are same, then
        // return true. Else return false.
        return (pDigit == sumDigits);
    }
      
    // Driver method
    public static void main (String[] args)
    {
       // Finding all prime numbers before limit. These
       // numbers are used to find prime factors.
       sieveSundaram();
       
       System.out.println("Printing first few Equidigital Numbers" +
                           " using isEquidigital()");
         
       for (int i=1; i<20; i++)
           if (isEquidigital(i))
               System.out.print(i + " ");
    }
}


Python3
# Python3 Program to find Equidigital 
# Numbers till n 
import math
MAX = 10000; 
  
# Array to store all prime less 
# than and equal to MAX. 
primes = []; 
  
# Utility function for sieve of sundaram 
def 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 
    marked = [False] * int(MAX / 2 + 1); 
  
    # Main logic of Sundaram. Mark all numbers which 
    # do not generate prime number by doing 2*i+1 
    for i in range(1, int((math.sqrt(MAX) - 1) / 2) + 1): 
        for j in range((i * (i + 1)) << 1, 
                    int(MAX / 2) + 1, 2 * i + 1): 
            marked[j] = True; 
  
    # Since 2 is a prime number 
    primes.append(2); 
  
    # Print other primes. Remaining primes 
    # are of the form 2*i + 1 such that 
    # marked[i] is false. 
    for i in range(1, int(MAX / 2) + 1): 
        if (marked[i] == False): 
            primes.append(2 * i + 1); 
  
# Returns true if n is a Equidigital 
# number, else false. 
def isEquidigital(n):
  
    if (n == 1): 
        return True; 
  
    # Count digits in original number 
    original_no = n; 
    sumDigits = 0; 
    while (original_no > 0):
        sumDigits += 1; 
        original_no = int(original_no / 10);
  
    # Count all digits in prime factors of n 
    # pDigit is going to hold this value. 
    pDigit = 0; 
    count_exp = 0; 
    p = 0;
    i = 0;
    while (primes[i] <= int(n / 2)): 
          
        # Count powers of p in n 
        while (n % primes[i] == 0):
              
            # If primes[i] is a prime factor, 
            p = primes[i]; 
            n = int(n / p); 
  
            # Count the power of prime factors 
            count_exp += 1;
  
        # Add its digits to pDigit. 
        while (p > 0): 
            pDigit += 1; 
            p = int(p / 10); 
  
        # Add digits of power of prime 
        # factors to pDigit. 
        while (count_exp > 1): 
            pDigit += 1; 
            count_exp = int(count_exp / 10);
        i += 1;
  
    # If n!=1 then one prime factor 
    # still to be summed up; 
    if (n != 1): 
        while (n > 0):
            pDigit += 1; 
            n = int(n / 10); 
  
    # If digits in prime factors and 
    # digits in original number are same, 
    # then return true. Else return false. 
    return (pDigit == sumDigits); 
  
# Driver code 
  
# Finding all prime numbers before 
# limit. These numbers are used to
# find prime factors. 
sieveSundaram(); 
  
print("Printing first few Equidigital", 
      "Numbers using isEquidigital()"); 
for i in range(1, 20): 
    if (isEquidigital(i)): 
        print(i, end = " "); 
          
# This code is contributed by mits


C#
// C# program to find Equidigital Numbers till n
using System; 
using System.Collections;
  
public class GFG 
{
    static int MAX = 10000;
    static ArrayList primes = new ArrayList(MAX+1);
      
    // 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];
      
        // 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);
    }
      
    // Returns true if n is a Equidigital number, else
    // false.
    static bool isEquidigital(int n)
    {
        if (n == 1)
            return true;
      
        // Count digits in original number
        int original_no = n;
        int sumDigits = 0;
        while (original_no > 0)
        {
            sumDigits++;
            original_no = original_no/10;
        }
      
      
        // Count all digits in prime factors of n
        // pDigit is going to hold this value.
        int pDigit = 0 , count_exp = 0, p = 0;
        for (int i = 0; (int)primes[i] <= n/2; i++)
        {
            // Count powers of p in n
            while (n % (int)primes[i] == 0)
            {
                // If primes[i] is a prime factor,
                p = (int)primes[i];
                n = n/p;
      
                // Count the power of prime factors
                count_exp++;
            }
      
            // Add its digits to pDigit.
            while (p > 0)
            {
                pDigit++;
                p = p / 10;
            }
      
            // Add digits of power of prime factors to pDigit.
            while (count_exp > 1)
            {
                pDigit++;
                count_exp = count_exp / 10;
            }
        }
      
        // If n!=1 then one prime factor still to be
        // summed up;
        if (n != 1)
        {
            while (n > 0)
            {
                pDigit++;
                n = n/10;
            }
        }
      
        // If digits in prime factors and
        // digits in original number are same, then
        // return true. Else return false.
        return (pDigit == sumDigits);
    }
      
    // Driver method
    public static void Main()
    {
    // Finding all prime numbers before limit. These
    // numbers are used to find prime factors.
    sieveSundaram();
      
    Console.WriteLine("Printing first few Equidigital Numbers using isEquidigital()");
          
    for (int i=1; i<20; i++)
        if (isEquidigital(i))
            Console.Write(i + " ");
    }
}
// This Code is contributed by mits


PHP
 0)
    {
        $sumDigits++;
        $original_no = (int)($original_no/10);
    }
  
  
    // Count all digits in prime factors of n
    // pDigit is going to hold this value.
    $pDigit = 0;
    $count_exp = 0;
    $p=0;
    for ($i = 0; $primes[$i] <= (int)($n/2); $i++)
    {
        // Count powers of p in n
        while ($n % $primes[$i] == 0)
        {
            // If primes[i] is a prime factor,
            $p = $primes[$i];
            $n = (int)($n/$p);
  
            // Count the power of prime factors
            $count_exp++;
        }
  
        // Add its digits to pDigit.
        while ($p > 0)
        {
            $pDigit++;
            $p =(int)($p / 10);
        }
  
        // Add digits of power of prime factors to pDigit.
        while ($count_exp > 1)
        {
            $pDigit++;
            $count_exp = (int)($count_exp / 10);
        }
    }
  
    // If n!=1 then one prime factor still to be
    // summed up;
    if ($n != 1)
    {
        while ($n > 0)
        {
            $pDigit++;
            $n = (int)($n/10);
        }
    }
  
    // If digits in prime factors and
    // digits in original number are same, then
    // return true. Else return false.
    return ($pDigit == $sumDigits);
}
  
// Driver code
  
    // Finding all prime numbers before limit. These
    // numbers are used to find prime factors.
    sieveSundaram();
  
    echo "Printing first few Equidigital Numbers using isEquidigital()\n";
    for ($i=1; $i<20; $i++)
        if (isEquidigital($i))
            echo $i." ";
              
              
// This code is contributed by mits
?>


输出:

Printing first few Equidigital Numbers using isEquidigital()
1 2 3 5 7 10 11 13 14 15 16 17 19

参考 :
https://zh.wikipedia.org/wiki/Equidigital_number