Find operations for Array Divisibility by Power of 2
Last Updated :
26 Apr, 2023
Given an array of size n, the task is to find the minimum number of operations required in the array such that the product of all array elements is divisible by nth power of 2. In one operation, you can select any index i and multiply ai by i, you can perform an operation on a particular index at most 1 time. (Follow 1-based indexing)
Examples:
Input: arr[] = { 10, 6, 11 }
Output: 1
Explanation: We can apply operation at index 2.
Input: arr[] = {13, 17, 1, 1 }
Output: -1
Explanation: We can not make the product such that divisible by 2n
Approach: To solve the problem follow the below idea:
We will apply operation till the product of the array is not divisible by 2n and apply operation on that index first which give us maximum 2s.
Illustration:
Lets take an example : arr[] = { 6, 1, 5, 1 }
- The product of the array is 30 which is not divisible by 24 here n=4
- We will apply an operation on index 4 because index 4 gives us maximum 2s than index 1, 2, 3. Then the product of the array becomes 120 which is not divisible by 24
- Then, we will apply an operation on index 2, because index 4 is already operated and index 2 gives a maximum 2 than index 1 and 3.
- Then, the product of the array becomes 240 which is divisible by 24.
- In total, it requires 2 operations to make the product of the array such that it is divisible by 2n.
Below are the steps for the above approach:
- Iterate the array to find how many 2s are present in the array initially.
- Iterate the array from the index from 1 to n and find how many 2s each number has and store the count in a vector say v and sort the vector in descending order because we want a maximum of 2s first.
- Initialize a boolean variable say flag = false.
- If the product of the array is divisible by the nth power of 2. The number of 2s in the product of the array should be greater than n.
- Iterate the vector v,
- Check if count2 >= n, update flag = true, and break the loop.
- Else perform the given operation such that, in minimum operation, we have the maximum number of 2s. In each iteration, add numbers of 2s present in that index stored in the vector v and increase operation by 1.
- Check if flag == true or count2 >= n which means the product if the array is divisible by 2n, returns the number of operations performed.
- If the product of the array is not divisible by 2n, return -1.
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int divisibleby( int * arr, int n)
{
int count2 = 0, temp2 = 0, oper = 0;
bool flag = false ;
vector< int > v;
for ( int i = 0; i < n; i++) {
while (arr[i] % 2 == 0) {
count2 += 1;
arr[i] = arr[i] / 2;
}
}
for ( int i = 1; i <= n; i++) {
int temp = i;
while (temp % 2 == 0) {
temp2 += 1;
temp = temp / 2;
}
if (temp2 > 0) {
v.push_back(temp2);
}
temp2 = 0;
}
sort(v.begin(), v.end(), greater< int >());
for ( int i = 0; i < v.size(); i++) {
if (count2 >= n) {
flag = true ;
break ;
}
else {
count2 += v[i];
oper += 1;
}
}
if (flag || count2 >= n) {
return oper;
}
return -1;
}
int main()
{
int arr[] = { 10, 6, 11 };
int n = sizeof (arr) / sizeof ( int );
cout << divisibleby(arr, n);
return 0;
}
|
Java
import java.util.*;
public class Main
{
static int divisibleby( int [] arr, int n) {
int count2 = 0 , temp2 = 0 , oper = 0 ;
boolean flag = false ;
List<Integer> v = new ArrayList<>();
for ( int i = 0 ; i < n; i++) {
while (arr[i] % 2 == 0 ) {
count2 += 1 ;
arr[i] = arr[i] / 2 ;
}
}
for ( int i = 1 ; i <= n; i++) {
int temp = i;
while (temp % 2 == 0 ) {
temp2 += 1 ;
temp = temp / 2 ;
}
if (temp2 > 0 ) {
v.add(temp2);
}
temp2 = 0 ;
}
Collections.sort(v, Collections.reverseOrder());
for ( int i = 0 ; i < v.size(); i++) {
if (count2 >= n) {
flag = true ;
break ;
}
else {
count2 += v.get(i);
oper += 1 ;
}
}
if (flag || count2 >= n) {
return oper;
}
return - 1 ;
}
public static void main(String[] args) {
int [] arr = { 10 , 6 , 11 };
int n = arr.length;
System.out.println(divisibleby(arr, n));
}
}
|
Python3
def divisibleby(arr, n):
count2 = 0
temp2 = 0
oper = 0
flag = False
v = []
for i in range (n):
while arr[i] % 2 = = 0 :
count2 + = 1
arr[i] / / = 2
for i in range ( 1 , n + 1 ):
temp = i
while temp % 2 = = 0 :
temp2 + = 1
temp / / = 2
if temp2 > 0 :
v.append(temp2)
temp2 = 0
v.sort(reverse = True )
for i in range ( len (v)):
if count2 > = n:
flag = True
break
else :
count2 + = v[i]
oper + = 1
if flag or count2 > = n:
return oper
return - 1
arr = [ 10 , 6 , 11 ]
n = len (arr)
print (divisibleby(arr, n))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class Program
{
public static int DivisibleBy( int [] arr, int n)
{
int count2 = 0, temp2 = 0, oper = 0;
bool flag = false ;
List< int > v = new List< int >();
for ( int i = 0; i < n; i++)
{
while (arr[i] % 2 == 0)
{
count2 += 1;
arr[i] = arr[i] / 2;
}
}
for ( int i = 1; i <= n; i++)
{
int temp = i;
while (temp % 2 == 0)
{
temp2 += 1;
temp = temp / 2;
}
if (temp2 > 0)
{
v.Add(temp2);
}
temp2 = 0;
}
v = v.OrderByDescending(i => i).ToList();
foreach ( int i in v)
{
if (count2 >= n)
{
flag = true ;
break ;
}
else
{
count2 += i;
oper += 1;
}
}
if (flag || count2 >= n)
{
return oper;
}
return -1;
}
public static void Main()
{
int [] arr = { 10, 6, 11 };
int n = arr.Length;
Console.WriteLine(DivisibleBy(arr, n));
}
}
|
Javascript
function divisibleby(arr, n) {
let count2 = 0, temp2 = 0, oper = 0;
let flag = false ;
let v = [];
for (let i = 0; i < n; i++) {
while (arr[i] % 2 == 0) {
count2 += 1;
arr[i] = arr[i] / 2;
}
}
for (let i = 1; i <= n; i++) {
let temp = i;
while (temp % 2 == 0) {
temp2 += 1;
temp = temp / 2;
}
if (temp2 > 0) {
v.push(temp2);
}
temp2 = 0;
}
v.sort( function (a, b) { return b - a });
for (let i = 0; i < v.length; i++) {
if (count2 >= n) {
flag = true ;
break ;
}
else {
count2 += v[i];
oper += 1;
}
}
if (flag || count2 >= n) {
return oper;
}
return -1;
}
let arr = [10, 6, 11];
let n = arr.length;
console.log(divisibleby(arr, n));
|
Time Complexity: O(n*log2n)
Auxiliary Space: O(n)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...