先决条件:使用筛子进行素因数分解
给定两个大小分别为M和N的数组arr1 []和arr2 [] ,每个数组中都有不同的元素,任务是查找乘积为a的那对元素(一个来自第一个数组,另一个来自第二个数组)。完美的正方形。如果无法形成对,则打印-1。
例子:
Input: arr1[] = {1, 8, 6, 9}, arr2[] = {2, 24, 49}
Output: (1, 49), (8, 2), (6, 24), (9, 49)
Explanation:
The product of pairs in the output are all perfect squares.
Pair 1: 1 x 49 = 49
Pair 2: 8 x 2 = 16
Pair 3: 6 x 24 = 144
Pair 4: 9 x 49 = 441
Input: arr1[] = {2, 3, 4}, arr2[] = {9, 5}
Output: -1
幼稚的方法:幼稚的方法是选择所有可能的对,并检查它们是否形成一个完美的正方形。这可以在二次时间内完成。
时间复杂度: O(M * N)
高效方法:该想法是使用素因数分解的概念。让我们分析一下如何在此问题中使用该概念。
以下是两个数字的乘积形成一个完美平方的情况:
- 如果两个数字都是完美的平方,则它们的乘积总是形成一个完美的平方。
- 如果其中一个数字不是一个完美的平方,那么它们的乘积就永远不可能是一个完美的平方。
- 如果两个数字都不是完美的平方,那么两个数字的素数的个数必须是偶数。
- 例如,
let x = 6, y = 1176
prime factorization of x = 2 x 3 (2 and 3 occurs odd times)
prime factorization of y = 2 x 2 x 2 x 3 x 7 x 7 (2 and 3 occurs odd times)
x * y = 7056 which is square of 84由于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)