Count of elements to be multiplied with integers to make each pair of Array a perfect square

Given an array arr[] containing positive integers, the task is to find the minimum number of operations to be done on the array to make every number of the array a superpower. 
In each operation, we can multiply any element of the array with an integer. 

A superpower is defined as a number in the array which when multiplied by any other number in the array apart from itself forms a perfect square. 

Examples: 

Input: arr[] = {2, 2, 2} 
Output:
Explanation: 
We don’t need to perform any operation on the array because on selecting any element (2) and multiplying it with any element in some other index (2), we get a perfect square (4). 

Input: arr[] = {2, 4, 6} 
Output:
Explanation: 
We need to perform the following two operations: 
First, we multiply the element at index 1 with integer 2. The array becomes {2, 8, 6}. 
Second, we multiply the element at index 2 with integer 3. The array becomes {2, 8, 18}. 
Now, all the elements have become a superpower. The multiplication of any two numbers from the array gives a perfect square. 
That is, 2 * 8 = 16, 2 * 16 = 36 and 8 * 18 = 144. 



Approach: Since we need to check the prime factors for all the numbers, the idea is to first precompute the unique prime factors of all the numbers and store it in a hashmap. Then, we create a variable to store the number of times that the prime factor appears in every single element of the array. We also need to observe that we need to find the minimum number of steps to convert the array. Therefore, we calculate the number of odd in the vector and the number of even prime factors, and whichever is the minimum, that will be the answer. The following steps can be computed to find the answer: 

  1. We first need to calculate the spf[] array. This is the array in which the smallest prime factor for all the elements is stored.
  2. Then, we need to find the unique prime factors and store it in the hashmap.
  3. Now, traverse the hash map to find the unique prime factors of a number and iterate over the elements in the given array to calculate the frequency of the prime factors.
  4. Now, two variables are initialized which stores the frequency of the prime number whose occurrence is even and another store the frequency of the prime numbers which is odd.
  5. Now, we need to add the minimum of the two variables in our final variable which is the minimum operation to attain superpower for that prime number.
  6. Repeat the above steps for all the numbers in the array.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program to find the minimum 
// number of steps to modify the 
// array such that the product 
// of any two numbers in the 
// array is a perfect square 
  
#include <iostream> 
#include <unordered_map> 
#include <vector> 
using namespace std; 
  
// Function to find the smallest 
// prime factor of the elements 
void spf_array(int spf[]) 
  
    // Initializing the first element 
    // of the array 
    spf[1] = 1; 
  
    // Loop to add the remaining 
    // elements to the array 
    for (int i = 2; i < 1000; i++) 
  
        // Marking the smallest prime 
        // factor for every 
        // number to be itself 
        spf[i] = i; 
  
    // Separately marking spf for 
    // every even number as 2 
    for (int i = 4; i < 1000; i += 2) 
        spf[i] = 2; 
  
    for (int i = 3; i * i < 1000; i++) { 
  
        // Checking if i is prime 
        if (spf[i] == i) { 
  
            // Marking SPF for all the 
            // numbers divisible by i 
            for (int j = i * i; j < 1000; j += i) 
  
                // Marking spf[j] if it is not 
                // previously marked 
                if (spf[j] == j) 
                    spf[j] = i; 
        
    
  
// Function to find the minimum 
// number of steps to modify the 
// array such that the product 
// of any two numbers in the 
// array is a perfect square 
int minimum_operation(int b[], int d, 
                    int spf[]) 
  
    // Map created to store 
    // the unique prime numbers 
    unordered_map<int, int> m; 
    int i = 0; 
  
    // Variable to store the 
    // minimum number of operations 
    int c = 0; 
  
    // Loop to store every 
    // unique prime number 
    for (i = 0; i < d; i++) { 
        int x = b[i]; 
        while (x != 1) { 
            x = x / spf[x]; 
            if (m[spf[x]] == 0) { 
                m[spf[x]] = 1; 
            
        
    
  
    // Erasing 1 as a key because 
    // it is not a prime number 
    m.erase(1); 
  
    // Iterating through the hash 
    for (auto x : m) { 
  
        // Two variables used for 
        // counting the frequency 
        // of prime is even or odd 
        int e = 0, o = 0; 
  
        // First prime number 
        int j = x.first; 
  
        // Iterating the number D 
        for (i = 0; i < d; i++) { 
  
            // check if prime is a 
            // factor of the element 
            // in the array 
            if (b[i] % j == 0) { 
                int h = 0; 
                int g = b[i]; 
  
                // Loop for calculating the 
                // frequency of the element 
                while (g != 0) { 
                    if (g % j != 0) { 
                        break
                    
                    g = g / j; 
                    h = h + 1; 
                
  
                // Check for frequency 
                // odd or even 
                if (h % 2 == 0) { 
                    e = e + 1; 
                
                else
                    o = o + 1; 
                
            
            else
  
                // If it is not a factor of the 
                // element, then it is automatically 
                // even 
                e = e + 1; 
            
        
  
        // Storing the minimum of two variable 
        // even or odd 
        c = c + min(o, e); 
    
    return c; 
  
// Driver code 
int main() 
    int spf[1001]; 
  
    // Input array 
    int b[] = { 1, 4, 6 }; 
  
    // Creating shortest prime 
    // factorisation array 
    int d = sizeof(b) / sizeof(b[0]); 
    spf_array(spf); 
  
    cout << minimum_operation(b, d, spf) 
        << endl; 

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program for the above approach
import java.io.*;
import java.util.*;
  
class GFG{
      
// Function to find the smallest
// prime factor of the elements
static void spf_array(int spf[])
{
  
    // Initializing the first element
    // of the array
    spf[1] = 1;
  
    // Loop to add the remaining
    // elements to the array
    for(int i = 2; i < 1000; i++)
  
        // Marking the smallest prime
        // factor for every
        // number to be itself
        spf[i] = i;
  
    // Separately marking spf for
    // every even number as 2
    for(int i = 4; i < 1000; i += 2)
        spf[i] = 2;
  
    for(int i = 3; i * i < 1000; i++) 
    {
  
        // Checking if i is prime
        if (spf[i] == i)
        {
              
            // Marking SPF for all the
            // numbers divisible by i
            for(int j = i * i; j < 1000; j += i)
  
                // Marking spf[j] if it is not
                // previously marked
                if (spf[j] == j)
                    spf[j] = i;
        }
    }
}
  
// Function to find the minimum
// number of steps to modify the
// array such that the product
// of any two numbers in the
// array is a perfect square
static int minimum_operation(int b[], int d,
                             int spf[])
{
      
    // Map created to store
    // the unique prime numbers
    Map<Integer, Integer> m=new HashMap<>();
    int i = 0;
  
    // Variable to store the
    // minimum number of operations
    int c = 0;
  
    // Loop to store every
    // unique prime number
    for(i = 0; i < d; i++)
    {
        int x = b[i];
        while (x != 1
        {
            x = x / spf[x];
            if (m.get(spf[x]) == null)
            {
                m.put(spf[x],1); 
            }
        }
    }
  
    // Erasing 1 as a key because
    // it is not a prime number
    m.remove(1);
  
    // Iterating through the hash
    for(Map.Entry<Integer,
                  Integer> x : m.entrySet()) 
    {
  
        // Two variables used for
        // counting the frequency
        // of prime is even or odd
        int e = 0, o = 0;
  
        // First prime number
        int j = x.getKey();
  
        // Iterating the number D
        for(i = 0; i < d; i++)
        {
  
            // Check if prime is a
            // factor of the element
            // in the array
            if (b[i] % j == 0)
            {
                int h = 0;
                int g = b[i];
  
                // Loop for calculating the
                // frequency of the element
                while (g != 0
                {
                    if (g % j != 0)
                    {
                        break;
                    }
                    g = g / j;
                    h = h + 1;
                }
  
                // Check for frequency
                // odd or even
                if (h % 2 == 0
                {
                    e = e + 1;
                }
                else
                {
                    o = o + 1;
                }
            }
            else 
            {
  
                // If it is not a factor of the
                // element, then it is automatically
                // even
                e = e + 1;
            }
        }
  
        // Storing the minimum of two variable
        // even or odd
        c = c + Math.min(o, e);
    }
    return c;
}
  
// Driver Code
public static void main (String[] args)
{
    int[] spf = new int[1001];
      
    // Input array
    int b[] = { 1, 4, 6 };
      
    // Creating shortest prime
    // factorisation array
    int d = b.length;
    spf_array(spf);
      
    System.out.print(minimum_operation(b, d, spf));
}
}
  
// This code is contributed by offbeat

chevron_right


Output: 

2

Time Complexity: O(N * log(N)), where N is the size of the input array.
 

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : nidhi_biet, offbeat