Given two numbers N and M, the task is to find the minimum operations required to convert N to M by repeatedly adding it with all even divisors of N except N. Print -1 if the conversion is not possible.
Examples:
Input: N = 6, M = 24
Output: 4
Explanation:
Step1: Add 2 (2 is an even divisor and 2!= 6) to 6. Now N becomes 8.
Step2: Add 4 (4 is an even divisor and 4!= 8) to 8. Now N becomes 12.
Step3: Add 6 (6 is an even divisor and 6!=12) to 12. Now N becomes 18.
Step4: Add 6 (6 is an even divisor and 6!=18) to 18. Now N becomes 24 = M.
Hence, 4 steps are needed.Input: N = 9, M = 17
Output: -1
Explanation:
There are no even divisors for 9 to add, so we cannot convert N to M.
Naive Approach: The simplest solution is to consider all possible even divisors of a number and calculate the answer for them recursively and finally return the minimum of it.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// INF is the maximum value // which indicates Impossible state const int INF = 1e7;
// Recursive Function that considers // all possible even divisors of cur int min_op( int cur, int M)
{ // Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
int op = INF;
// Loop to find even divisors of cur
for ( int i = 2; i * i <= cur; i++) {
// if i is divisor of cur
if (cur % i == 0) {
// if i is even
if (i % 2 == 0) {
// Finding divisors
// recursively for cur+i
op = min(op,
1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i
&& (cur / i) % 2 == 0) {
// Find recursively
// for cur+(cur/i)
op = min(
op,
1 + min_op(
cur + (cur / i),
M));
}
}
}
// Return the answer
return op;
} // Function that finds the minimum // operation to reduce N to M int min_operations( int N, int M)
{ int op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
cout << "-1" ;
else
cout << op << "\n" ;
} // Driver Code int main()
{ // Given N and M
int N = 6, M = 24;
// Function Call
min_operations(N, M);
return 0;
} |
// Java program for the above approach class GFG{
// INF is the maximum value // which indicates Impossible state static int INF = ( int ) 1e7;
// Recursive Function that considers // all possible even divisors of cur static int min_op( int cur, int M)
{ // Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0 ;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
int op = INF;
// Loop to find even divisors of cur
for ( int i = 2 ; i * i <= cur; i++)
{
// if i is divisor of cur
if (cur % i == 0 )
{
// if i is even
if (i % 2 == 0 )
{
// Finding divisors
// recursively for cur+i
op = Math.min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0 )
{
// Find recursively
// for cur+(cur/i)
op = Math.min(op, 1 + min_op(
cur + (cur / i), M));
}
}
}
// Return the answer
return op;
} // Function that finds the minimum // operation to reduce N to M static void min_operations( int N, int M)
{ int op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
System.out.print( "-1" );
else
System.out.print(op + "\n" );
} // Driver Code public static void main(String[] args)
{ // Given N and M
int N = 6 , M = 24 ;
// Function Call
min_operations(N, M);
} } // This code is contributed by gauravrajput1 |
# Python3 program for the above approach # INF is the maximum value # which indicates Impossible state INF = int ( 1e7 );
# Recursive Function that considers # all possible even divisors of cur def min_op(cur, M):
# Indicates impossible state
if (cur > M):
return INF;
# Return 0 if cur == M
if (cur = = M):
return 0 ;
# op stores the minimum operations
# required to transform cur to M
# Initially it is set to INF that
# means we can't transform cur to M
op = int (INF);
# Loop to find even divisors of cur
for i in range ( 2 , int (cur * * 1 / 2 ) + 1 ):
# If i is divisor of cur
if (cur % i = = 0 ):
# If i is even
if (i % 2 = = 0 ):
# Finding divisors
# recursively for cur+i
op = min (op, 1 + min_op(cur + i, M));
# Check another divisor
if ((cur / i) ! = i and
(cur / i) % 2 = = 0 ):
# Find recursively
# for cur+(cur/i)
op = min (op, 1 + min_op(
cur + (cur / / i), M));
# Return the answer
return op;
# Function that finds the minimum # operation to reduce N to M def min_operations(N, M):
op = min_op(N, M);
# INF indicates impossible state
if (op > = INF):
print ( "-1" );
else :
print (op);
# Driver Code if __name__ = = '__main__' :
# Given N and M
N = 6 ;
M = 24 ;
# Function call
min_operations(N, M);
# This code is contributed by Amit Katiyar |
// C# program for the above approach using System;
class GFG {
// INF is the maximum value
// which indicates Impossible state
static int INF = ( int )1e7;
// Recursive Function that considers
// all possible even divisors of cur
static int min_op( int cur, int M)
{
// Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
int op = INF;
// Loop to find even divisors of cur
for ( int i = 2; i * i <= cur; i++)
{
// if i is divisor of cur
if (cur % i == 0)
{
// if i is even
if (i % 2 == 0)
{
// Finding divisors
// recursively for cur+i
op = Math.Min(op,1 +
min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
// Return the answer
return op;
}
// Function that finds the minimum
// operation to reduce N to M
static void min_operations( int N, int M)
{
int op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
Console.Write( "-1" );
else
Console.Write(op + "\n" );
}
// Driver Code
public static void Main(String[] args)
{
// Given N and M
int N = 6, M = 24;
// Function Call
min_operations(N, M);
}
} // This code is contributed by Amit Katiyar |
<script> // Javascript program to implement // the above approach // INF is the maximum value // which indicates Impossible state let INF = 1e7; // Recursive Function that considers // all possible even divisors of cur function min_op(cur, M)
{ // Indicates impossible state
if (cur > M)
return INF;
// Return 0 if cur == M
if (cur == M)
return 0;
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// means we can't transform cur to M
let op = INF;
// Loop to find even divisors of cur
for (let i = 2; i * i <= cur; i++)
{
// if i is divisor of cur
if (cur % i == 0)
{
// if i is even
if (i % 2 == 0)
{
// Finding divisors
// recursively for cur+i
op = Math.min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.min(op, 1 + min_op(
cur + (cur / i), M));
}
}
}
// Return the answer
return op;
} // Function that finds the minimum // operation to reduce N to M function min_operations(N, M)
{ let op = min_op(N, M);
// INF indicates impossible state
if (op >= INF)
document.write( "-1" );
else
document.write(op + "\n" );
} // Driver Code // Given N and M
let N = 6, M = 24;
// Function Call
min_operations(N, M);
</script> |
4
Time Complexity: O(2N)
Auxiliary Space: O(1)
Efficient Approach: The idea is to use Dynamic Programming and store the overlapping subproblems state in the naive approach to calculate the answer efficiently. Follow the below steps to solve the problem:
- Initialize a dp table dp[i] = -1 for all N?i?M.
- Consider all possible even divisors of a number and find the minimum from all of it.
- Finally, store the result in dp[] and return the answer.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// INF is the maximum value // which indicates Impossible state const int INF = 1e7;
const int max_size = 100007;
// Stores the dp states int dp[max_size];
// Recursive Function that considers // all possible even divisors of cur int min_op( int cur, int M)
{ // Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for ( int i = 2; i * i <= cur; i++) {
// if i is divisor of cur
if (cur % i == 0) {
// if i is even
if (i % 2 == 0) {
// Find recursively
// for cur+i
op = min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0) {
// Find recursively
// for cur+(cur/i)
op = min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
} // Function that counts the minimum // operation to reduce N to M int min_operations( int N, int M)
{ // Initialise dp state
for ( int i = N; i <= M; i++) {
dp[i] = -1;
}
// Function Call
return min_op(N, M);
} // Driver Code int main()
{ // Given N and M
int N = 6, M = 24;
// Function Call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
cout << "-1" ;
else
cout << op << "\n" ;
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG{
// INF is the maximum value // which indicates Impossible state static int INF = ( int ) 1e7;
static int max_size = 100007 ;
// Stores the dp states static int []dp = new int [max_size];
// Recursive Function that considers // all possible even divisors of cur static int min_op( int cur, int M)
{ // Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0 ;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != - 1 )
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for ( int i = 2 ; i * i <= cur; i++)
{
// If i is divisor of cur
if (cur % i == 0 )
{
// If i is even
if (i % 2 == 0 )
{
// Find recursively
// for cur+i
op = Math.min(op,
1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i &&
(cur / i) % 2 == 0 )
{
// Find recursively
// for cur+(cur/i)
op = Math.min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
} // Function that counts the minimum // operation to reduce N to M static int min_operations( int N, int M)
{ // Initialise dp state
for ( int i = N; i <= M; i++)
{
dp[i] = - 1 ;
}
// Function call
return min_op(N, M);
} // Driver Code public static void main(String[] args)
{ // Given N and M
int N = 6 , M = 24 ;
// Function call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
System.out.print( "-1" );
else
System.out.print(op + "\n" );
} } // This code is contributed by Amit Katiyar |
# Python3 program for the # above approach # INF is the maximum value # which indicates Impossible state INF = 10000007 ;
max_size = 100007 ;
# Stores the dp states dp = [ 0 for i in range (max_size)];
# Recursive Function # that considers all # possible even divisors # of cur def min_op(cur, M):
# Indicates impossible
# state
if (cur > M):
return INF;
if (cur = = M):
return 0 ;
# Check dp[cur] is already
# calculated or not
if (dp[cur] ! = - 1 ):
return dp[cur];
# op stores the minimum
# operations required to
# transform cur to M
# Initially it is set
# to INF that meanswe cur
# can't be transform to M
op = INF;
i = 2
# Loop to find even
# divisors of cur
while (i * i < = cur):
# if i is divisor of cur
if (cur % i = = 0 ):
# if i is even
if (i % 2 = = 0 ):
# Find recursively
# for cur+i
op = min (op, 1 + min_op(cur +
i, M));
# Check another divisor
if ((cur / / i) ! = i and
(cur / / i) % 2 = = 0 ):
# Find recursively
# for cur+(cur/i)
op = min (op, 1 + min_op(cur +
(cur / / i), M))
i + = 1 # Finally store the current state
# result and return the answer
dp[cur] = op;
return op
# Function that counts the minimum # operation to reduce N to M def min_operations(N, M):
# Initialise dp state
for i in range (N, M + 1 ):
dp[i] = - 1 ;
# Function Call
return min_op(N, M);
# Driver code if __name__ = = "__main__" :
# Given N and M
N = 6
M = 24
# Function Call
op = min_operations(N, M);
# INF indicates impossible state
if (op > = INF):
print ( - 1 )
else :
print (op)
# This code is contributed by rutvik_56 |
// C# program for the above approach using System;
class GFG{
// INF is the maximum value // which indicates Impossible state static int INF = ( int ) 1e7;
static int max_size = 100007;
// Stores the dp states static int []dp = new int [max_size];
// Recursive Function that considers // all possible even divisors of cur static int min_op( int cur, int M)
{ // Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
int op = INF;
// Loop to find even divisors of cur
for ( int i = 2; i * i <= cur; i++)
{
// If i is divisor of cur
if (cur % i == 0)
{
// If i is even
if (i % 2 == 0)
{
// Find recursively
// for cur+i
op = Math.Min(op, 1 +
min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i &&
(cur / i) % 2 == 0)
{
// Find recursively
// for cur+(cur/i)
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
} // Function that counts the minimum // operation to reduce N to M static int min_operations( int N,
int M)
{ // Initialise dp state
for ( int i = N; i <= M; i++)
{
dp[i] = -1;
}
// Function call
return min_op(N, M);
} // Driver Code public static void Main(String[] args)
{ // Given N and M
int N = 6, M = 24;
// Function call
int op = min_operations(N, M);
// INF indicates impossible state
if (op >= INF)
Console.Write( "-1" );
else
Console.Write(op + "\n" );
} } // This code is contributed by Rajput-Ji |
<script> // Javascript program for the above approach // INF is the maximum value // which indicates Impossible state var INF = 10000000;
var max_size = 100007;
// Stores the dp states var dp = Array(max_size);
// Recursive Function that considers // all possible even divisors of cur function min_op( cur, M)
{ // Indicates impossible state
if (cur > M)
return INF;
if (cur == M)
return 0;
// Check dp[cur] is already
// calculated or not
if (dp[cur] != -1)
return dp[cur];
// op stores the minimum operations
// required to transform cur to M
// Initially it is set to INF that
// meanswe cur can't be transform to M
var op = INF;
// Loop to find even divisors of cur
for ( var i = 2; i * i <= cur; i++) {
// if i is divisor of cur
if (cur % i == 0) {
// if i is even
if (i % 2 == 0) {
// Find recursively
// for cur+i
op = Math.min(op, 1 + min_op(cur + i, M));
}
// Check another divisor
if ((cur / i) != i && (cur / i) % 2 == 0) {
// Find recursively
// for cur+(cur/i)
op = Math.min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
// Finally store the current state
// result and return the answer
return dp[cur] = op;
} // Function that counts the minimum // operation to reduce N to M function min_operations(N, M)
{ // Initialise dp state
for ( i = N; i <= M; i++) {
dp[i] = -1;
}
// Function Call
return min_op(N, M);
} // Driver Code // Given N and M var N = 6, M = 24;
// Function Call var op = min_operations(N, M);
// INF indicates impossible state if (op >= INF)
document.write( "-1" );
else document.write( op + "<br>" );
// This code is contributed by noob2000. </script> |
4
Time Complexity: O(N*sqrt(N))
Auxiliary Space: O(M)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a table to store the solution of the subproblems.
- Initialize the table with base cases
- Fill up the table iteratively
- Return the final solution
Implementation :
#include <bits/stdc++.h> using namespace std;
// Define a constant for impossible states const int INF = 1e7;
int min_operations( int N, int M)
{ // Initialize dp table with INF
int dp[M+1];
for ( int i = 0; i <= M; i++) {
dp[i] = INF;
}
// Base case
dp[N] = 0;
// Fill up dp table
for ( int i = N; i < M; i++) {
// Skip impossible states
if (dp[i] >= INF) {
continue ;
}
for ( int j = 2; j * j <= i; j++) {
if (i % j == 0) {
if (j % 2 == 0) {
int next = i + j;
if (next <= M) {
// Update the minimum number of operations to reach 'next'
dp[next] = min(dp[next], dp[i] + 1);
}
}
if ((i / j) != j && (i / j) % 2 == 0) {
int next = i + (i / j);
if (next <= M) {
// Update the minimum number of operations to reach 'next'
dp[next] = min(dp[next], dp[i] + 1);
}
}
}
}
}
// Return the answer
if (dp[M] >= INF) {
// It's impossible to reach M from N, so print -1
cout << "-1\n" ;
} else {
// Print the minimum number of operations to reach M from N
cout << dp[M] << "\n" ;
}
} // Driver Code int main()
{ // Given N and M
int N = 6, M = 24;
// Function Call
min_operations(N, M);
return 0;
} // this code is contributed by bhardwajji |
import java.util.*;
class Main {
// Define a constant for impossible states
static final int INF = 10000000 ;
static int minOperations( int N, int M)
{
// Initialize dp table with INF
int [] dp = new int [M + 1 ];
Arrays.fill(dp, INF);
// Base case
dp[N] = 0 ;
// Fill up dp table
for ( int i = N; i < M; i++) {
// Skip impossible states
if (dp[i] >= INF) {
continue ;
}
for ( int j = 2 ; j * j <= i; j++) {
if (i % j == 0 ) {
if (j % 2 == 0 ) {
int next = i + j;
if (next <= M) {
// Update the minimum number of
// operations to reach 'next'
dp[next] = Math.min(dp[next],
dp[i] + 1 );
}
}
if ((i / j) != j && (i / j) % 2 == 0 ) {
int next = i + (i / j);
if (next <= M) {
// Update the minimum number of
// operations to reach 'next'
dp[next] = Math.min(dp[next],
dp[i] + 1 );
}
}
}
}
}
// Return the answer
if (dp[M] >= INF) {
// It's impossible to reach M from N, so print
// -1
System.out.println( "-1" );
}
else {
// Print the minimum number of operations to
// reach M from N
System.out.println(dp[M]);
}
return 0 ;
}
// Driver Code
public static void main(String[] args)
{
// Given N and M
int N = 6 , M = 24 ;
// Function Call
minOperations(N, M);
}
} |
# Define a constant for impossible states INF = 10 * * 7
def min_operations(N: int , M: int ) - > None :
# Initialize dp table with INF
dp = [INF] * (M + 1 )
# Base case
dp[N] = 0
# Fill up dp table
for i in range (N, M):
# Skip impossible states
if dp[i] > = INF:
continue
for j in range ( 2 , int (i * * 0.5 ) + 1 ):
if i % j = = 0 :
if j % 2 = = 0 :
next = i + j
if next < = M:
# Update the minimum number of operations to reach 'next'
dp[ next ] = min (dp[ next ], dp[i] + 1 )
if (i / / j) ! = j and (i / / j) % 2 = = 0 :
next = i + (i / / j)
if next < = M:
# Update the minimum number of operations to reach 'next'
dp[ next ] = min (dp[ next ], dp[i] + 1 )
# Return the answer
if dp[M] > = INF:
# It's impossible to reach M from N, so print -1
print ( "-1" )
else :
# Print the minimum number of operations to reach M from N
print (dp[M])
# Driver Code if __name__ = = '__main__' :
# Given N and M
N, M = 6 , 24
# Function Call
min_operations(N, M)
|
using System;
public class MainClass
{ // Define a constant for impossible states
static readonly int INF = 10000000;
static int minOperations( int N, int M)
{
// Initialize dp table with INF
int [] dp = new int [M + 1];
Array.Fill(dp, INF);
// Base case
dp[N] = 0;
// Fill up dp table
for ( int i = N; i < M; i++)
{
// Skip impossible states
if (dp[i] >= INF)
{
continue ;
}
for ( int j = 2; j * j <= i; j++)
{
if (i % j == 0)
{
if (j % 2 == 0)
{
int next = i + j;
if (next <= M)
{
// Update the minimum number of
// operations to reach 'next'
dp[next] = Math.Min(dp[next],
dp[i] + 1);
}
}
if ((i / j) != j && (i / j) % 2 == 0)
{
int next = i + (i / j);
if (next <= M)
{
// Update the minimum number of
// operations to reach 'next'
dp[next] = Math.Min(dp[next],
dp[i] + 1);
}
}
}
}
}
// Return the answer
if (dp[M] >= INF)
{
// It's impossible to reach M from N, so print
// -1
Console.WriteLine( "-1" );
}
else
{
// Print the minimum number of operations to
// reach M from N
Console.WriteLine(dp[M]);
}
return 0;
}
// Driver Code
public static void Main( string [] args)
{
// Given N and M
int N = 6, M = 24;
// Function Call
minOperations(N, M);
}
} |
// Define a constant for impossible states const INF = 1e7; function min_operations(N, M) {
// Initialize dp table with INF
let dp = Array(M+1).fill(INF);
// Base case
dp[N] = 0;
// Fill up dp table
for (let i = N; i < M; i++) {
// Skip impossible states
if (dp[i] >= INF) {
continue ;
}
for (let j = 2; j * j <= i; j++) {
if (i % j == 0) {
if (j % 2 == 0) {
let next = i + j;
if (next <= M) {
// Update the minimum number of operations to reach 'next'
dp[next] = Math.min(dp[next], dp[i] + 1);
}
}
if ((i / j) != j && (i / j) % 2 == 0) {
let next = i + (i / j);
if (next <= M) {
// Update the minimum number of operations to reach 'next'
dp[next] = Math.min(dp[next], dp[i] + 1);
}
}
}
}
}
// Return the answer
if (dp[M] >= INF) {
// It's impossible to reach M from N, so print -1
console.log( "-1" );
} else {
// Print the minimum number of operations to reach M from N
console.log(dp[M]);
}
} // Driver Code let N = 6, M = 24; // Function Call min_operations(N, M); |
4
Time Complexity : O(M * sqrt(M))
Auxiliary Space: O(M)