Open In App

Minimize multiply by position so that Array product is divisible by 2^K

Last Updated : 09 Dec, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array nums [] of size N containing positive integers and a positive integer K, the task is to find the minimum number of operations such that the array product is divisible by 2K where in each operation nums[i] is multiplied by its position (i.e. i+1).

Note: Return -1 if it is not possible to make the array product divisible 2K.  

Examples:

Input: N = 2, K = 2, nums[] = { 3, 2 }
Output: 1
Explanation: The product of nums is 6 which is not divisible by 22 = 4. Make nums[2] = 2 * 2 = 4, then the product of the array becomes 12 which is divisible by 22.

Input: N = 3, K = 3, nums[] = { 2, 1, 3 }
Output: -1
Explanation: The product of nums is 6 which is not divisible by 23 = 8. If we make nums[2] = 1 * 2 = 2, then also the product will become 12 which is not divisible by 23.

Approach: This can be solved using the following idea:

Count the number of times each element of array and index i is divisible by 2 and store the count of each in a variable and check whether count of two is more than K or not.

Follow the below steps to solve the problem:

  • Initialize a variable (say curr = 0).
  • Traverse the array nums[] and store the number of 2s in the factorization of each element in curr variable and the number of 2s in index i and store them in a vector v.
  • If the curr variable is greater than or equal to K then return 0.
  • Sort the vector v in increasing order.
  • Initialize res = 0 to count the number of operations required.
    • While curr value is less than K and v is not empty, optimally increase the curr by v.back() i.e. maximum number of two’s in indices [1, n], pop back from v and increment in res by 1.
  • When the traversal is over, check if the current value is still less than K then return -1.
  • Otherwise, return res as the number of operations required.

Below is the implementation of the above approach.

C++




// C++ code to implement the approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to count the number of
// 2s in factorization of n
int countTwos(int n)
{
    // Initialize count = 0 to store count
    int count = 0;
 
    while (n % 2 == 0) {
        count++;
        n /= 2;
    }
 
    // Return count of 2
    return count;
}
 
// Function to count min operations
// required to make product divisible by 2^k
int minimumOperationsReq(vector<int>& nums, int k)
{
    // To store number of 2s
    // in factorization of nums[i]
    int curr = 0;
 
    // Initialise a vector to store number
    // of 2s in factorization for each
    // index
    vector<int> v;
 
    // Traversal to count number of 2s
    // initially in nums[i] and for each
    // index
    for (int i = 0; i < nums.size(); i++) {
 
        // Increment in curr by how many times
        // 2 is in prime factorisation of
        // nums[i]
        curr += countTwos(nums[i]);
 
        // Initialise cnt to store by how many
        // times 2 is in prime
        // factorisation of index i + 1
        int cnt = countTwos(i + 1);
 
        // Store cnt in vector v
        v.push_back(cnt);
    }
 
    // Already the product is divisible by 2^k
    if (curr >= k)
        return 0;
 
    // Sort the vector containing number
    // of 2s in each index
    sort(v.begin(), v.end());
 
    // Initialise res = 0 to count number of
    // operations required
    int res = 0;
 
    // Traversal for counting the operations
    // to make product divisible by 2^k
    while (curr < k and !v.empty()) {
 
        // Increment in curr
        curr += v.back();
 
        // Delete the last element of
        // vector v
        v.pop_back();
 
        // Increment in res by 1 i.e,
        // increase number of operation
        res++;
    }
 
    // If number of 2s still less than k
    // than it is not possible, return -1
    if (curr < k)
        return -1;
 
    // Return number of operations required
    return res;
}
 
// Driver code
int main()
{
    int K = 2;
    vector<int> nums = { 3, 2 };
    int N = nums.size();
 
    // Function call
    cout << minimumOperationsReq(nums, K);
 
    return 0;
}


Java




// Java code to implement the approach
import java.util.*;
class GFG{
 
// Function to count the number of
// 2s in factorization of n
static int countTwos(int n)
{
    // Initialize count = 0 to store count
    int count = 0;
 
    while (n % 2 == 0) {
        count++;
        n /= 2;
    }
 
    // Return count of 2
    return count;
}
 
// Function to count min operations
// required to make product divisible by 2^k
static int minimumOperationsReq(int[] nums, int k)
{
    // To store number of 2s
    // in factorization of nums[i]
    int curr = 0;
 
    // Initialise a vector to store number
    // of 2s in factorization for each
    // index
    ArrayList<Integer> v = new ArrayList<>();
 
    // Traversal to count number of 2s
    // initially in nums[i] and for each
    // index
    for (int i = 0; i < nums.length; i++) {
 
        // Increment in curr by how many times
        // 2 is in prime factorisation of
        // nums[i]
        curr += countTwos(nums[i]);
 
        // Initialise cnt to store by how many
        // times 2 is in prime
        // factorisation of index i + 1
        int cnt = countTwos(i + 1);
 
        // Store cnt in vector v
        v.add(cnt);
    }
 
    // Already the product is divisible by 2^k
    if (curr >= k)
        return 0;
 
    // Sort the vector containing number
    // of 2s in each index
    Collections.sort(v);  
 
    // Initialise res = 0 to count number of
    // operations required
    int res = 0;
 
    // Traversal for counting the operations
    // to make product divisible by 2^k
    while (curr < k && !v.isEmpty()) {
 
        // Increment in curr
        curr += v.get(v.size()-1);
 
        // Delete the last element of
        // vector v
        v.remove(v.size()-1);
 
        // Increment in res by 1 i.e,
        // increase number of operation
        res++;
    }
 
    // If number of 2s still less than k
    // than it is not possible, return -1
    if (curr < k)
        return -1;
 
    // Return number of operations required
    return res;
}
 
// Driver code
public static void main(String[] args)
{
    int K = 2;
    int[] nums = { 3, 2 };
    int N = nums.length;
 
    // Function call
    System.out.println(minimumOperationsReq(nums, K));
}
}
 
// This code is contributed by Pushpesh Raj.


Python3




# Python3 code to implement the approach
 
# Function to count the number of
# 2s in factorization of n
def countTwos(n) :
 
    # Initialize count = 0 to store count
    count = 0;
 
    while (n % 2 == 0) :
        count += 1;
        n //= 2;
 
    # Return count of 2
    return count;
 
# Function to count min operations
# required to make product divisible by 2^k
def minimumOperationsReq(nums, k) :
 
    # To store number of 2s
    # in factorization of nums[i]
    curr = 0;
 
    # Initialise a vector to store number
    # of 2s in factorization for each
    # index
    v = [];
 
    # Traversal to count number of 2s
    # initially in nums[i] and for each
    # index
    for i in range(len(nums)) :
 
        # Increment in curr by how many times
        # 2 is in prime factorisation of
        # nums[i]
        curr += countTwos(nums[i]);
 
        # Initialise cnt to store by how many
        # times 2 is in prime
        # factorisation of index i + 1
        cnt = countTwos(i + 1);
 
        # Store cnt in vector v
        v.append(cnt);
 
    # Already the product is divisible by 2^k
    if (curr >= k) :
        return 0;
 
    # Sort the vector containing number
    # of 2s in each index
    v.sort();
 
    # Initialise res = 0 to count number of
    # operations required
    res = 0;
 
    # Traversal for counting the operations
    # to make product divisible by 2^k
    while (curr < k and len(v) !=0) :
 
        # Increment in curr
        curr += v[-1];
 
        # Delete the last element of
        # vector v
        v.pop();
 
        # Increment in res by 1 i.e,
        # increase number of operation
        res += 1;
 
    # If number of 2s still less than k
    # than it is not possible, return -1
    if (curr < k) :
        return -1;
 
    # Return number of operations required
    return res;
 
# Driver code
if __name__ == "__main__" :
 
    K = 2;
    nums = [ 3, 2 ];
    N = len(nums);
 
    # Function call
    print(minimumOperationsReq(nums, K));
 
   # This code is contributed by AnkThon


C#




// C# code to implement the approach
using System;
using System.Collections;
using System.Collections.Generic;
 
class GFG {
 
    // Function to count the number of
    // 2s in factorization of n
    static int countTwos(int n)
    {
        // Initialize count = 0 to store count
        int count = 0;
 
        while (n % 2 == 0) {
            count++;
            n /= 2;
        }
 
        // Return count of 2
        return count;
    }
 
    // Function to count min operations
    // required to make product divisible by 2^k
    static int minimumOperationsReq(int[] nums, int k)
    {
        // To store number of 2s
        // in factorization of nums[i]
        int curr = 0;
 
        // Initialise a vector to store number
        // of 2s in factorization for each
        // index
        ArrayList v = new ArrayList();
 
        // Traversal to count number of 2s
        // initially in nums[i] and for each
        // index
        for (int i = 0; i < nums.Length; i++) {
 
            // Increment in curr by how many times
            // 2 is in prime factorisation of
            // nums[i]
            curr += countTwos(nums[i]);
 
            // Initialise cnt to store by how many
            // times 2 is in prime
            // factorisation of index i + 1
            int cnt = countTwos(i + 1);
 
            // Store cnt in vector v
            v.Add(cnt);
        }
 
        // Already the product is divisible by 2^k
        if (curr >= k)
            return 0;
 
        // Sort the vector containing number
        // of 2s in each index
        v.Sort();
 
        // Initialise res = 0 to count number of
        // operations required
        int res = 0;
 
        // Traversal for counting the operations
        // to make product divisible by 2^k
        while (curr < k && v.Count > 0) {
 
            // Increment in curr
            curr += (int)v[v.Count - 1];
 
            // Delete the last element of
            // vector v
            v.RemoveAt(v.Count - 1);
 
            // Increment in res by 1 i.e,
            // increase number of operation
            res++;
        }
 
        // If number of 2s still less than k
        // than it is not possible, return -1
        if (curr < k)
            return -1;
 
        // Return number of operations required
        return res;
    }
 
    // Driver code
    public static void Main()
    {
        int K = 2;
        int[] nums = { 3, 2 };
        int N = nums.Length;
 
        // Function call
        Console.WriteLine(minimumOperationsReq(nums, K));
    }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript




<script>
    // JavaScript code for the above approach
 
 
    // Function to count the number of
    // 2s in factorization of n
    function countTwos(n) {
      // Initialize count = 0 to store count
      let count = 0;
 
      while (n % 2 == 0) {
        count++;
        n /= 2;
      }
 
      // Return count of 2
      return count;
    }
 
    // Function to count min operations
    // required to make product divisible by 2^k
    function minimumOperationsReq(nums, k) {
      // To store number of 2s
      // in factorization of nums[i]
      let curr = 0;
 
      // Initialise a vector to store number
      // of 2s in factorization for each
      // index
      let v = [];
 
      // Traversal to count number of 2s
      // initially in nums[i] and for each
      // index
      for (let i = 0; i < nums.length; i++) {
 
        // Increment in curr by how many times
        // 2 is in prime factorisation of
        // nums[i]
        curr += countTwos(nums[i]);
 
        // Initialise cnt to store by how many
        // times 2 is in prime
        // factorisation of index i + 1
        let cnt = countTwos(i + 1);
 
        // Store cnt in vector v
        v.push(cnt);
      }
 
      // Already the product is divisible by 2^k
      if (curr >= k)
        return 0;
 
      // Sort the vector containing number
      // of 2s in each index
      v.sort(function (a, b) { return a - b })
 
      // Initialise res = 0 to count number of
      // operations required
      let res = 0;
 
      // Traversal for counting the operations
      // to make product divisible by 2^k
      while (curr < k && v.length != 0) {
 
        // Increment in curr
        curr += v[v.length - 1];
 
        // Delete the last element of
        // vector v
        v.pop();
 
        // Increment in res by 1 i.e,
        // increase number of operation
        res++;
      }
 
      // If number of 2s still less than k
      // than it is not possible, return -1
      if (curr < k)
        return -1;
 
      // Return number of operations required
      return res;
    }
 
    // Driver code
    let K = 2;
    let nums = [3, 2];
    let N = nums.length;
 
    // Function call
    document.write(minimumOperationsReq(nums, K));
 
 // This code is contributed by Potta Lokesh
 
  </script>


Output

1

Time Complexity: O(N * log N)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads