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++ 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 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 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# 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.
<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)