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 |
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) { // Intialise 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) { // Intialise 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): # Intialise 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) { // Intialise 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 |
4
Time Complexity: O(N*sqrt(N))
Auxiliary Space: O(M)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.