📜  在给定数组中查找史密斯兄弟对的数量

📅  最后修改于: 2022-05-13 01:56:08.517000             🧑  作者: Mango

在给定数组中查找史密斯兄弟对的数量

给定一个大小为N的数组A[] ,任务是计算数组中的Smith Brothers Pairs

注意:史密斯数是一个复合数,其位数之和等于其素数分解中的位数之和。

例子

天真的方法:天真的方法是使用嵌套循环遍历每个可能的对,并检查数字是否是 Smith Brothers Pairs。请按照以下步骤解决问题:

  1. 将变量count初始化为0 ,它将 Smith Brothers Pairs 的数量存储在数组中。
  2. 遍历数组A0N-1 。对于每个当前索引i ,请执行以下操作:
    1. i+1遍历AN-1 。对于每个当前索引j ,请执行以下操作:
      1. 检查A[i]A[j]是否为 smith 数。
      2. 如果它们是 smith 数并且它们的差为 1,则增加计数。
  3. 最后,返回计数

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#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()
{
    bool marked[MAX / 2 + 100] = { 0 };
 
    // Main logic of Sundaram.
    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);
 
    // only primes are selected
    for (int i = 1; i <= MAX / 2; i++)
        if (marked[i] == false)
            primes.push_back(2 * i + 1);
}
 
// Function to check whether a number is a smith number.
bool isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
    for (int i = 0; primes[i] <= n / 2; i++) {
        while (n % primes[i] == 0) {
            // add its digits of prime factors to pDigitSum.
            int p = primes[i];
            n = n / p;
            while (p > 0) {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // one prime factor is still to be summed up
    if (n != 1 && n != original_no) {
        while (n > 0) {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0) {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
bool isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y) && abs(X - Y) == 1;
}
 
// Function to find pairs from array
int countSmithBrotherPairs(int A[], int N)
{
    int count = 0;
    // Iterate through all pairs
    for (int i = 0; i < N; i++)
        for (int j = i + 1; j < N; j++) {
            // Increment count if there is a smith brother
            // pair
            if (isSmithBrotherPair(A[i], A[j]))
                count++;
        }
    return count;
}
 
// Driver code
int main()
{
    // Preprocessing
    sieveSundaram();
    // Input
    int A[] = { 728, 729, 28, 2964, 2965 };
    int N = sizeof(A) / sizeof(A[0]);
 
    // Function call
    cout << countSmithBrotherPairs(A, N) << endl;
    return 0;
}


Java
// Java program for the above approach
import java.util.ArrayList;
 
class GFG{
 
static int MAX = 10000;
 
// Array to store all prime less than and equal to MAX
static ArrayList primes = new ArrayList();
 
// Utility function for sieve of sundaram
public static void sieveSundaram()
{
    ArrayList marked = new ArrayList(
        MAX / 2 + 100);
 
    for(int i = 0; i < MAX / 2 + 100; i++)
    {
        marked.add(false);
    }
     
    // Main logic of Sundaram.
    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.set(j, true);
 
    // Since 2 is a prime number
    primes.add(2);
 
    // Only primes are selected
    for(int i = 1; i <= MAX / 2; i++)
        if (marked.get(i) == false)
            primes.add(2 * i + 1);
}
 
// Function to check whether a number is a smith number.
public static Boolean isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
     
    for(int i = 0; primes.get(i) <= n / 2; i++)
    {
        while (n % primes.get(i) == 0)
        {
             
            // Add its digits of prime factors
            // to pDigitSum.
            int p = primes.get(i);
            n = n / p;
             
            while (p > 0)
            {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // One prime factor is still to be summed up
    if (n != 1 && n != original_no)
    {
        while (n > 0)
        {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
     
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0)
    {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // Return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
public static Boolean isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y) &&
           Math.abs(X - Y) == 1;
}
 
// Function to find pairs from array
public static Integer countSmithBrotherPairs(int A[],
                                             int N)
{
    int count = 0;
     
    // Iterate through all pairs
    for(int i = 0; i < N; i++)
        for(int j = i + 1; j < N; j++)
        {
             
            // Increment count if there is a
            // smith brother pair
            if (isSmithBrotherPair(A[i], A[j]))
                count++;
        }
    return count;
}
 
// Driver code
public static void main(String args[])
{
     
    // Preprocessing
    sieveSundaram();
     
    // Input
    int A[] = { 728, 729, 28, 2964, 2965 };
    int N = A.length;
 
    // Function call
    System.out.println(countSmithBrotherPairs(A, N));
}
}
 
// This code is contributed by _saurabh_jaiswal


Python3
# Python3 program for the above approach
from math import sqrt
MAX = 10000
 
# Array to store all prime less than
# and equal to MAX
primes = []
 
# Utility function for sieve of sundaram
def sieveSundaram():
     
    marked = [0 for i in range(MAX // 2 + 100)]
 
    # Main logic of Sundaram.
    j = 0
    for i in range(1, int((sqrt(MAX) - 1) / 2) + 1, 1):
        for j in range((i * (i + 1)) << 1,
                      MAX // 2 + 1, j + 2 * i + 1):
            marked[j] = True
 
    # Since 2 is a prime number
    primes.append(2)
 
    # only primes are selected
    for i in range(1, MAX // 2 + 1, 1):
        if (marked[i] == False):
            primes.append(2 * i + 1)
 
# Function to check whether a number
# is a smith number.
def isSmith(n):
     
    original_no = n
 
    # Find sum the digits of prime
    # factors of n
    pDigitSum = 0
    i = 0
     
    while (primes[i] <= n // 2):
        while (n % primes[i] == 0):
             
            # Add its digits of prime factors
            # to pDigitSum.
            p = primes[i]
            n = n // p
             
            while (p > 0):
                pDigitSum += (p % 10)
                p = p // 10
                 
        i += 1
 
    # One prime factor is still to be summed up
    if (n != 1 and n != original_no):
        while (n > 0):
            pDigitSum = pDigitSum + n % 10
            n = n // 10
 
    # Now sum the digits of the original number
    sumDigits = 0
     
    while (original_no > 0):
        sumDigits = sumDigits + original_no % 10
        original_no = original_no // 10
 
    # Return the answer
    return (pDigitSum == sumDigits)
 
# Function to check if X and Y are a
# Smith Brother Pair
def isSmithBrotherPair(X, Y):
     
    return (isSmith(X) and isSmith(Y) and
            abs(X - Y) == 1)
 
# Function to find pairs from array
def countSmithBrotherPairs(A, N):
     
    count = 0
     
    # Iterate through all pairs
    for i in range(N):
        for j in range(i + 1, N, 1):
             
            # Increment count if there is a
            # smith brother pair
            if (isSmithBrotherPair(A[i], A[j])):
                count += 1
 
    return count
 
# Driver code
if __name__ == '__main__':
     
    # Preprocessing
    sieveSundaram()
     
    # Input
    A = [ 728, 729, 28, 2964, 2965 ]
    N = len(A)
 
    # Function call
    print(countSmithBrotherPairs(A, N))
     
# This code is contributed by SURENDRA_GANGWAR


C#
// C# program for the above approach
using System;
using System.Collections.Generic;
 
class GFG{
 
static int MAX = 10000;
 
// array to store all prime less than and equal to MAX
static List primes = new List();
 
// utility function for sieve of sundaram
static void sieveSundaram()
{
    int []marked = new int[MAX / 2 + 100];
    Array.Clear(marked,0,MAX/2 +100);
 
    // Main logic of Sundaram.
    for (int i = 1; i <= (int)(Math.Sqrt(MAX) - 1) / 2; i++)
        for (int j = (i * (i + 1)) << 1; j <= MAX / 2;
             j = j + 2 * i + 1)
             marked[j] = 1;
 
    // Since 2 is a prime number
    primes.Add(2);
 
    // only primes are selected
    for (int i = 1; i <= (int)MAX / 2; i++)
        if (marked[i] == 0)
            primes.Add(2 * i + 1);
}
 
// Function to check whether a number is a smith number.
static bool isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
    for (int i = 0; primes[i] <= n / 2; i++)
    {
        while (n % primes[i] == 0)
        {
           
            // add its digits of prime factors to pDigitSum.
            int p = primes[i];
            n = n / p;
            while (p > 0) {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // one prime factor is still to be summed up
    if (n != 1 && n != original_no) {
        while (n > 0) {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
   
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0) {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
static bool isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y) && Math.Abs(X - Y) == 1;
}
 
// Function to find pairs from array
static int countSmithBrotherPairs(int []A, int N)
{
    int count = 0;
   
    // Iterate through all pairs
    for (int i = 0; i < N; i++)
        for (int j = i + 1; j < N; j++)
        {
           
            // Increment count if there is a smith brother
            // pair
            if (isSmithBrotherPair(A[i], A[j]))
                count++;
        }
    return count;
}
 
// Driver code
public static void Main()
{
    // Preprocessing
    sieveSundaram();
   
    // Input
    int []A = { 728, 729, 28, 2964, 2965 };
    int N = A.Length;
 
    // Function call
    Console.Write(countSmithBrotherPairs(A, N));
}
}
 
// This code is contributed by SURENDRA_GANGWAR.


Javascript


C++
// C++ program for the above approach
 
#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()
{
    bool marked[MAX / 2 + 100] = { 0 };
 
    // Main logic of Sundaram.
    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);
 
    // only primes are selected
    for (int i = 1; i <= MAX / 2; i++)
        if (marked[i] == false)
            primes.push_back(2 * i + 1);
}
 
// Function to check whether
// a number is a smith number.
bool isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
    for (int i = 0; primes[i] <= n / 2; i++) {
        while (n % primes[i] == 0) {
            // add its digits of
            // prime factors to pDigitSum.
            int p = primes[i];
            n = n / p;
            while (p > 0) {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // one prime factor is still to be summed up
    if (n != 1 && n != original_no) {
        while (n > 0) {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0) {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
bool isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y);
}
 
// Function to find pairs from array
int countSmithBrotherPairs(int A[], int N)
{
    // Variable to store number
    // of Smith Brothers Pairs
    int count = 0;
    // sort A
    sort(A, A + N);
    // check for consecutive numbers only
    for (int i = 0; i < N - 2; i++)
        if (isSmithBrotherPair(A[i], A[i + 1]))
            count++;
    return count;
}
 
// Driver code
int main()
{
    // Preprocessing sieve of sundaram
    sieveSundaram();
    // Input
    int A[] = { 728, 729, 28, 2964, 2965 };
    int N = sizeof(A) / sizeof(A[0]);
 
    // Function call
    cout << countSmithBrotherPairs(A, N) << endl;
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
 
class GFG {
 
static int MAX = 10000;
 
// array to store all prime
// less than and equal to MAX
static ArrayList primes = new ArrayList();
 
// utility function for sieve of sundaram
static void sieveSundaram()
{
     ArrayList marked = new ArrayList(
        MAX / 2 + 100);
 
    for(int i = 0; i < MAX / 2 + 100; i++)
    {
        marked.add(false);
    }
 
    // Main logic of Sundaram.
    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.set(j, true);
 
    // Since 2 is a prime number
    primes.add(2);
 
    // only primes are selected
    for (int i = 1; i <= MAX / 2; i++)
        if (marked.get(i) == false)
            primes.add(2 * i + 1);
}
 
// Function to check whether
// a number is a smith number.
static Boolean isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
    for (int i = 0; primes.get(i) <= n / 2; i++) {
        while (n % primes.get(i) == 0) {
            // add its digits of
            // prime factors to pDigitSum.
            int p = primes.get(i);
            n = n / p;
            while (p > 0) {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // one prime factor is still to be summed up
    if (n != 1 && n != original_no) {
        while (n > 0) {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0) {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
static Boolean isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y);
}
 
// Function to find pairs from array
static Integer countSmithBrotherPairs(int A[], int N)
{
    // Variable to store number
    // of Smith Brothers Pairs
    int count = 0;
   
    // sort A
    Arrays.sort(A);
   
    // check for consecutive numbers only
    for (int i = 0; i < N - 2; i++)
        if (isSmithBrotherPair(A[i], A[i + 1]))
            count++;
    return count;
}
 
// Driver Code
public static void main(String[] args)
{
    // Preprocessing sieve of sundaram
    sieveSundaram();
    // Input
    int A[] = { 728, 729, 28, 2964, 2965 };
    int N = A.length;
 
    // Function call
    System.out.print(countSmithBrotherPairs(A, N));
}
}
 
// This code is contributed by avijitmondal1998.


Javascript


输出
2

时间复杂度: O(M+N 2 )
辅助空间: O(M)

有效方法:由于只有连续的 smith 数字可以形成 Smith Brothers Pairs,因此最佳解决方案是对数组A进行排序。然后,仅检查连续元素。
请按照以下步骤解决问题。

  1. 将变量count初始化为0
  2. 对数组A进行排序。
  3. 遍历A从 0 到N-2 ,对于每个当前索引i ,执行以下操作:
    1. 检查A[i]A[i+1]是否都是史密斯数。
    2. 如果它们都是史密斯数,则增加count
  4. 最后,返回count

下面是上述方法的实现:

C++

// C++ program for the above approach
 
#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()
{
    bool marked[MAX / 2 + 100] = { 0 };
 
    // Main logic of Sundaram.
    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);
 
    // only primes are selected
    for (int i = 1; i <= MAX / 2; i++)
        if (marked[i] == false)
            primes.push_back(2 * i + 1);
}
 
// Function to check whether
// a number is a smith number.
bool isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
    for (int i = 0; primes[i] <= n / 2; i++) {
        while (n % primes[i] == 0) {
            // add its digits of
            // prime factors to pDigitSum.
            int p = primes[i];
            n = n / p;
            while (p > 0) {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // one prime factor is still to be summed up
    if (n != 1 && n != original_no) {
        while (n > 0) {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0) {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
bool isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y);
}
 
// Function to find pairs from array
int countSmithBrotherPairs(int A[], int N)
{
    // Variable to store number
    // of Smith Brothers Pairs
    int count = 0;
    // sort A
    sort(A, A + N);
    // check for consecutive numbers only
    for (int i = 0; i < N - 2; i++)
        if (isSmithBrotherPair(A[i], A[i + 1]))
            count++;
    return count;
}
 
// Driver code
int main()
{
    // Preprocessing sieve of sundaram
    sieveSundaram();
    // Input
    int A[] = { 728, 729, 28, 2964, 2965 };
    int N = sizeof(A) / sizeof(A[0]);
 
    // Function call
    cout << countSmithBrotherPairs(A, N) << endl;
    return 0;
}

Java

// Java program for the above approach
import java.util.*;
 
class GFG {
 
static int MAX = 10000;
 
// array to store all prime
// less than and equal to MAX
static ArrayList primes = new ArrayList();
 
// utility function for sieve of sundaram
static void sieveSundaram()
{
     ArrayList marked = new ArrayList(
        MAX / 2 + 100);
 
    for(int i = 0; i < MAX / 2 + 100; i++)
    {
        marked.add(false);
    }
 
    // Main logic of Sundaram.
    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.set(j, true);
 
    // Since 2 is a prime number
    primes.add(2);
 
    // only primes are selected
    for (int i = 1; i <= MAX / 2; i++)
        if (marked.get(i) == false)
            primes.add(2 * i + 1);
}
 
// Function to check whether
// a number is a smith number.
static Boolean isSmith(int n)
{
    int original_no = n;
 
    // Find sum the digits of prime factors of n
    int pDigitSum = 0;
    for (int i = 0; primes.get(i) <= n / 2; i++) {
        while (n % primes.get(i) == 0) {
            // add its digits of
            // prime factors to pDigitSum.
            int p = primes.get(i);
            n = n / p;
            while (p > 0) {
                pDigitSum += (p % 10);
                p = p / 10;
            }
        }
    }
 
    // one prime factor is still to be summed up
    if (n != 1 && n != original_no) {
        while (n > 0) {
            pDigitSum = pDigitSum + n % 10;
            n = n / 10;
        }
    }
    // Now sum the digits of the original number
    int sumDigits = 0;
    while (original_no > 0) {
        sumDigits = sumDigits + original_no % 10;
        original_no = original_no / 10;
    }
 
    // return the answer
    return (pDigitSum == sumDigits);
}
 
// Function to check if X and Y are a
// Smith Brother Pair
static Boolean isSmithBrotherPair(int X, int Y)
{
    return isSmith(X) && isSmith(Y);
}
 
// Function to find pairs from array
static Integer countSmithBrotherPairs(int A[], int N)
{
    // Variable to store number
    // of Smith Brothers Pairs
    int count = 0;
   
    // sort A
    Arrays.sort(A);
   
    // check for consecutive numbers only
    for (int i = 0; i < N - 2; i++)
        if (isSmithBrotherPair(A[i], A[i + 1]))
            count++;
    return count;
}
 
// Driver Code
public static void main(String[] args)
{
    // Preprocessing sieve of sundaram
    sieveSundaram();
    // Input
    int A[] = { 728, 729, 28, 2964, 2965 };
    int N = A.length;
 
    // Function call
    System.out.print(countSmithBrotherPairs(A, N));
}
}
 
// This code is contributed by avijitmondal1998.

Javascript


输出
2

时间复杂度: O(M+NLogN)
辅助空间: O(M)

参考:https://mathworld.wolfram.com/SmithBrothers.html