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++
// 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
// 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
# 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#
// 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 |
Javascript
<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++
// 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
// 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
# 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#
// 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 |
Javascript
<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 :
C++
#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 |
Java
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); } } |
Python3
# 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) |
C#
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); } } |
Javascript
// 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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!