📌  相关文章
📜  从两个不同的数组中查找成对的元素,它们的乘积是一个完美的平方

📅  最后修改于: 2021-04-24 05:12:36             🧑  作者: Mango

先决条件:使用筛子进行素因数分解

给定两个大小分别为MN的数组arr1 []arr2 [] ,每个数组中都有不同的元素,任务是查找乘积为a的那对元素(一个来自第一个数组,另一个来自第二个数组)。完美的正方形。如果无法形成对,则打印-1。

例子:

幼稚的方法:幼稚的方法是选择所有可能的对,并检查它们是否形成一个完美的正方形。这可以在二次时间内完成。
时间复杂度: O(M * N)

高效方法:该想法是使用素因数分解的概念。让我们分析一下如何在此问题中使用该概念。
以下是两个数字的乘积形成一个完美平方的情况:

  • 如果两个数字都是完美的平方,则它们的乘积总是形成一个完美的平方。
  • 如果其中一个数字不是一个完美的平方,那么它们的乘积就永远不可能是一个完美的平方。
  • 如果两个数字都不是完美的平方,那么两个数字的素数的个数必须是偶数。
  • 例如,

    由于x和y具有所有奇数次出现的素数,但是x * y具有偶数个素数因子。因此,它们将形成一个完美的正方形。

因此,阵列ARR1 []被遍历并为ARR1每个元素[],在阵列ARR2 []具有的素数发生作为当前元素的奇次同样的产品的数量。这可以在登录时使用C++中的map STL来完成。

下面是上述方法的实现:

C++
// C++ program to print pairs whose
// product is a perfect square
#include 
using namespace std;
  
// Maximum number upto which sieve is performed
#define MAXN 100001
  
// Array to perform Sieve of Eratosthenes
// and store prime numbers
int spf[MAXN];
  
// Function to perform sieve of
// eratosthenes on the array spf.
void sieve()
{
    spf[1] = 1;
    for (int i = 2; i < MAXN; i++)
        spf[i] = i;
  
    for (int i = 4; i < MAXN; i += 2)
        spf[i] = 2;
  
    for (int i = 3; i * i < MAXN; i++) {
        if (spf[i] == i) {
            for (int j = i * i; j < MAXN; j += i)
  
                if (spf[j] == j)
                    spf[j] = i;
        }
    }
}
  
// Function to return the product of the
// odd occurring prime factors of a number
int getProductOddOccuringPrimes(int x)
{
    // Product of 1 with perfect square gives
    // perfect square, 1 is returned for x = 1
    if (x == 1)
        return 1;
  
    // Temperory container of prime factors
    vector ret;
    while (x != 1) {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
  
    // ans contains the product of primes
    // which occurs odd number of times
    int count = 1, ans = 1;
    for (int i = 0, j = 1; j < ret.size(); ++j, ++i) {
        if (ret[i] != ret[j]) {
            if (count & 1)
                ans *= ret[i];
            count = 0;
        }
        count++;
    }
  
    // Checks if count is odd or not
    if (count & 1)
        ans *= ret[ret.size() - 1];
  
    return ans;
}
  
// Function to print the pairs whose product is
// a perfect square
void printPairs(int n, int m, int a[], int b[])
{
    int countPairs = 0;
  
    // For storing the indicies with same
    // product of odd times occuring Primes as key
    map > productOfPrimes;
  
    // Every number from both the array is iterated
    // getProductOddOccuringPrimes function is called
    // and the product of odd occurring primes is
    // stored in the map productOfPrimes.
    // A pair is printed if the product is same
    for (int i = 0; i < n; ++i) {
  
        // Generating the product of odd times
        // occurring primes
        int productPrimesOfA
            = getProductOddOccuringPrimes(a[i]);
  
        // Pushing the indices to the to the
        // vector with the product of
        // odd times occurring Primes
        productOfPrimes[productPrimesOfA].push_back(i);
    }
  
    for (int i = 0; i < m; ++i) {
        // Generating the product of odd times
        // occurring Primes
        int productPrimesOfB
            = getProductOddOccuringPrimes(b[i]);
  
        // Checking if productPrimesOfB
        // lies in the productOfPrimes
        if (productOfPrimes.find(productPrimesOfB)
            != productOfPrimes.end()) {
            for (auto itr : productOfPrimes[productPrimesOfB]) {
                countPairs++;
                cout << " (" << b[i] << ", "
                     << a[itr] << ") ";
            }
        }
    }
    if (countPairs <= 0)
        cout << "No pairs Found!";
    cout << endl;
}
// Driver function
int main()
{
    sieve();
  
    // N, M are size of array a and b respectively
    int N = 5, M = 5;
    int a[] = { 4, 1, 6, 35, 120 };
    int b[] = { 24, 140, 4, 30, 1 };
  
    // Function that prints the pairs
    // whose product is a perfect square
    printPairs(N, M, a, b);
    return 0;
}


Java
// Java program to print pairs whose
// product is a perfect square
import java.util.*;
  
class GFG{
  
// Maximum number upto which sieve is performed
static final int MAXN = 100001;
  
// Array to perform Sieve of Eratosthenes
// and store prime numbers
static int []spf = new int[MAXN];
  
// Function to perform sieve of
// eratosthenes on the array spf.
static void sieve()
{
    spf[1] = 1;
    for (int i = 2; i < MAXN; i++)
        spf[i] = i;
  
    for (int i = 4; i < MAXN; i += 2)
        spf[i] = 2;
  
    for (int i = 3; i * i < MAXN; i++) {
        if (spf[i] == i) {
            for (int j = i * i; j < MAXN; j += i)
  
                if (spf[j] == j)
                    spf[j] = i;
        }
    }
}
  
// Function to return the product of the
// odd occurring prime factors of a number
static int getProductOddOccuringPrimes(int x)
{
    // Product of 1 with perfect square gives
    // perfect square, 1 is returned for x = 1
    if (x == 1)
        return 1;
  
    // Temperory container of prime factors
    Vector ret = new Vector();
    while (x != 1) {
        ret.add(spf[x]);
        x = x / spf[x];
    }
  
    // ans contains the product of primes
    // which occurs odd number of times
    int count = 1, ans = 1;
    for (int i = 0, j = 1; j < ret.size(); ++j, ++i) {
        if (ret.get(i) != ret.get(j)) {
            if (count % 2 == 1)
                ans *= ret.get(i);
            count = 0;
        }
        count++;
    }
  
    // Checks if count is odd or not
    if (count %2 == 1)
        ans *= ret.get(ret.size() - 1);
  
    return ans;
}
  
// Function to print the pairs whose product is
// a perfect square
static void printPairs(int n, int m, int a[], int b[])
{
    int countPairs = 0;
  
    // For storing the indicies with same
    // product of odd times occuring Primes as key
    Map> productOfPrimes =
            new HashMap>();
  
    // Every number from both the array is iterated
    // getProductOddOccuringPrimes function is called
    // and the product of odd occurring primes is
    // stored in the map productOfPrimes.
    // A pair is printed if the product is same
    for (int i = 0; i < n; ++i) {
  
        // Generating the product of odd times
        // occurring primes
        int productPrimesOfA
            = getProductOddOccuringPrimes(a[i]);
  
        // Pushing the indices to the to the
        // vector with the product of
        // odd times occurring Primes
        Vector temp = new Vector();
        if(productOfPrimes.containsKey(productPrimesOfA))
        for (Integer s:productOfPrimes.get(productPrimesOfA)){
            temp.add(s);
        }
        temp.add(i);
        productOfPrimes.put(productPrimesOfA, temp);
    }
  
    for (int i = 0; i < m; ++i)
    {
          
        // Generating the product of odd times
        // occurring Primes
        int productPrimesOfB
            = getProductOddOccuringPrimes(b[i]);
  
        // Checking if productPrimesOfB
        // lies in the productOfPrimes
        if (productOfPrimes.containsKey(productPrimesOfB)) {
            for (Integer itr : productOfPrimes.get(productPrimesOfB)) {
                countPairs++;
                System.out.print(" (" + b[i]+ ", "
                    + a[itr]+ ") ");
            }
        }
    }
    if (countPairs <= 0)
        System.out.print("No pairs Found!");
    System.out.println();
}
  
// Driver function
public static void main(String[] args)
{
    sieve();
  
    // N, M are size of array a and b respectively
    int N = 5, M = 5;
    int a[] = { 4, 1, 6, 35, 120 };
    int b[] = { 24, 140, 4, 30, 1 };
  
    // Function that prints the pairs
    // whose product is a perfect square
    printPairs(N, M, a, b);
}
}
  
// This code is contributed by 29AjayKumar


C#
// C# program to print pairs whose
// product is a perfect square
using System;
using System.Collections.Generic;
  
class GFG{
   
// Maximum number upto which sieve is performed
static readonly int MAXN = 100001;
   
// Array to perform Sieve of Eratosthenes
// and store prime numbers
static int []spf = new int[MAXN];
   
// Function to perform sieve of
// eratosthenes on the array spf.
static void sieve()
{
    spf[1] = 1;
    for (int i = 2; i < MAXN; i++)
        spf[i] = i;
   
    for (int i = 4; i < MAXN; i += 2)
        spf[i] = 2;
   
    for (int i = 3; i * i < MAXN; i++) {
        if (spf[i] == i) {
            for (int j = i * i; j < MAXN; j += i)
   
                if (spf[j] == j)
                    spf[j] = i;
        }
    }
}
   
// Function to return the product of the
// odd occurring prime factors of a number
static int getProductOddOccuringPrimes(int x)
{
    // Product of 1 with perfect square gives
    // perfect square, 1 is returned for x = 1
    if (x == 1)
        return 1;
   
    // Temperory container of prime factors
    List ret = new List();
    while (x != 1) {
        ret.Add(spf[x]);
        x = x / spf[x];
    }
   
    // ans contains the product of primes
    // which occurs odd number of times
    int count = 1, ans = 1;
    for (int i = 0, j = 1; j < ret.Count; ++j, ++i) {
        if (ret[i] != ret[j]) {
            if (count % 2 == 1)
                ans *= ret[i];
            count = 0;
        }
        count++;
    }
   
    // Checks if count is odd or not
    if (count %2 == 1)
        ans *= ret[ret.Count - 1];
   
    return ans;
}
   
// Function to print the pairs whose product is
// a perfect square
static void printPairs(int n, int m, int []a, int []b)
{
    int countPairs = 0;
   
    // For storing the indicies with same
    // product of odd times occuring Primes as key
    Dictionary> productOfPrimes =
            new Dictionary>();
   
    // Every number from both the array is iterated
    // getProductOddOccuringPrimes function is called
    // and the product of odd occurring primes is
    // stored in the map productOfPrimes.
    // A pair is printed if the product is same
    for (int i = 0; i < n; ++i) {
   
        // Generating the product of odd times
        // occurring primes
        int productPrimesOfA
            = getProductOddOccuringPrimes(a[i]);
   
        // Pushing the indices to the to the
        // vector with the product of
        // odd times occurring Primes
        List temp = new List();
        if(productOfPrimes.ContainsKey(productPrimesOfA))
        foreach (int s in productOfPrimes[productPrimesOfA]){
            temp.Add(s);
        }
        temp.Add(i);
        if(productOfPrimes.ContainsKey(productPrimesOfA))
            productOfPrimes[productPrimesOfA] = temp;
        else
            productOfPrimes.Add(productPrimesOfA, temp);
    }
   
    for (int i = 0; i < m; ++i)
    {
           
        // Generating the product of odd times
        // occurring Primes
        int productPrimesOfB
            = getProductOddOccuringPrimes(b[i]);
   
        // Checking if productPrimesOfB
        // lies in the productOfPrimes
        if (productOfPrimes.ContainsKey(productPrimesOfB)) {
            foreach (int itr in productOfPrimes[productPrimesOfB]) {
                countPairs++;
                Console.Write(" (" + b[i]+ ", "
                    + a[itr]+ ") ");
            }
        }
    }
    if (countPairs <= 0)
        Console.Write("No pairs Found!");
    Console.WriteLine();
}
   
// Driver function
public static void Main(String[] args)
{
    sieve();
   
    // N, M are size of array a and b respectively
    int N = 5, M = 5;
    int []a = { 4, 1, 6, 35, 120 };
    int []b = { 24, 140, 4, 30, 1 };
   
    // Function that prints the pairs
    // whose product is a perfect square
    printPairs(N, M, a, b);
}
}
  
// This code is contributed by 29AjayKumar


输出:
(24, 6)  (140, 35)  (4, 4)  (4, 1)  (30, 120)  (1, 4)  (1, 1)

时间复杂度: O(Klog(K)),其中K = max(N,M)