Minimum repeated addition of even divisors of N required to convert N to M
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++
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e7;
int min_op( int cur, int M)
{
if (cur > M)
return INF;
if (cur == M)
return 0;
int op = INF;
for ( int i = 2; i * i <= cur; i++) {
if (cur % i == 0) {
if (i % 2 == 0) {
op = min(op,
1 + min_op(cur + i, M));
}
if ((cur / i) != i
&& (cur / i) % 2 == 0) {
op = min(
op,
1 + min_op(
cur + (cur / i),
M));
}
}
}
return op;
}
int min_operations( int N, int M)
{
int op = min_op(N, M);
if (op >= INF)
cout << "-1" ;
else
cout << op << "\n" ;
}
int main()
{
int N = 6, M = 24;
min_operations(N, M);
return 0;
}
|
Java
class GFG{
static int INF = ( int ) 1e7;
static int min_op( int cur, int M)
{
if (cur > M)
return INF;
if (cur == M)
return 0 ;
int op = INF;
for ( int i = 2 ; i * i <= cur; i++)
{
if (cur % i == 0 )
{
if (i % 2 == 0 )
{
op = Math.min(op, 1 + min_op(cur + i, M));
}
if ((cur / i) != i && (cur / i) % 2 == 0 )
{
op = Math.min(op, 1 + min_op(
cur + (cur / i), M));
}
}
}
return op;
}
static void min_operations( int N, int M)
{
int op = min_op(N, M);
if (op >= INF)
System.out.print( "-1" );
else
System.out.print(op + "\n" );
}
public static void main(String[] args)
{
int N = 6 , M = 24 ;
min_operations(N, M);
}
}
|
Python3
INF = int ( 1e7 );
def min_op(cur, M):
if (cur > M):
return INF;
if (cur = = M):
return 0 ;
op = int (INF);
for i in range ( 2 , int (cur * * 1 / 2 ) + 1 ):
if (cur % i = = 0 ):
if (i % 2 = = 0 ):
op = min (op, 1 + min_op(cur + i, M));
if ((cur / i) ! = i and
(cur / i) % 2 = = 0 ):
op = min (op, 1 + min_op(
cur + (cur / / i), M));
return op;
def min_operations(N, M):
op = min_op(N, M);
if (op > = INF):
print ( "-1" );
else :
print (op);
if __name__ = = '__main__' :
N = 6 ;
M = 24 ;
min_operations(N, M);
|
C#
using System;
class GFG {
static int INF = ( int )1e7;
static int min_op( int cur, int M)
{
if (cur > M)
return INF;
if (cur == M)
return 0;
int op = INF;
for ( int i = 2; i * i <= cur; i++)
{
if (cur % i == 0)
{
if (i % 2 == 0)
{
op = Math.Min(op,1 +
min_op(cur + i, M));
}
if ((cur / i) != i && (cur / i) % 2 == 0)
{
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
return op;
}
static void min_operations( int N, int M)
{
int op = min_op(N, M);
if (op >= INF)
Console.Write( "-1" );
else
Console.Write(op + "\n" );
}
public static void Main(String[] args)
{
int N = 6, M = 24;
min_operations(N, M);
}
}
|
Javascript
<script>
let INF = 1e7;
function min_op(cur, M)
{
if (cur > M)
return INF;
if (cur == M)
return 0;
let op = INF;
for (let i = 2; i * i <= cur; i++)
{
if (cur % i == 0)
{
if (i % 2 == 0)
{
op = Math.min(op, 1 + min_op(cur + i, M));
}
if ((cur / i) != i && (cur / i) % 2 == 0)
{
op = Math.min(op, 1 + min_op(
cur + (cur / i), M));
}
}
}
return op;
}
function min_operations(N, M)
{
let op = min_op(N, M);
if (op >= INF)
document.write( "-1" );
else
document.write(op + "\n" );
}
let N = 6, M = 24;
min_operations(N, M);
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
const int INF = 1e7;
const int max_size = 100007;
int dp[max_size];
int min_op( int cur, int M)
{
if (cur > M)
return INF;
if (cur == M)
return 0;
if (dp[cur] != -1)
return dp[cur];
int op = INF;
for ( int i = 2; i * i <= cur; i++) {
if (cur % i == 0) {
if (i % 2 == 0) {
op = min(op, 1 + min_op(cur + i, M));
}
if ((cur / i) != i && (cur / i) % 2 == 0) {
op = min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
return dp[cur] = op;
}
int min_operations( int N, int M)
{
for ( int i = N; i <= M; i++) {
dp[i] = -1;
}
return min_op(N, M);
}
int main()
{
int N = 6, M = 24;
int op = min_operations(N, M);
if (op >= INF)
cout << "-1" ;
else
cout << op << "\n" ;
return 0;
}
|
Java
import java.util.*;
class GFG{
static int INF = ( int ) 1e7;
static int max_size = 100007 ;
static int []dp = new int [max_size];
static int min_op( int cur, int M)
{
if (cur > M)
return INF;
if (cur == M)
return 0 ;
if (dp[cur] != - 1 )
return dp[cur];
int op = INF;
for ( int i = 2 ; i * i <= cur; i++)
{
if (cur % i == 0 )
{
if (i % 2 == 0 )
{
op = Math.min(op,
1 + min_op(cur + i, M));
}
if ((cur / i) != i &&
(cur / i) % 2 == 0 )
{
op = Math.min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
return dp[cur] = op;
}
static int min_operations( int N, int M)
{
for ( int i = N; i <= M; i++)
{
dp[i] = - 1 ;
}
return min_op(N, M);
}
public static void main(String[] args)
{
int N = 6 , M = 24 ;
int op = min_operations(N, M);
if (op >= INF)
System.out.print( "-1" );
else
System.out.print(op + "\n" );
}
}
|
Python3
INF = 10000007 ;
max_size = 100007 ;
dp = [ 0 for i in range (max_size)];
def min_op(cur, M):
if (cur > M):
return INF;
if (cur = = M):
return 0 ;
if (dp[cur] ! = - 1 ):
return dp[cur];
op = INF;
i = 2
while (i * i < = cur):
if (cur % i = = 0 ):
if (i % 2 = = 0 ):
op = min (op, 1 + min_op(cur +
i, M));
if ((cur / / i) ! = i and
(cur / / i) % 2 = = 0 ):
op = min (op, 1 + min_op(cur +
(cur / / i), M))
i + = 1
dp[cur] = op;
return op
def min_operations(N, M):
for i in range (N, M + 1 ):
dp[i] = - 1 ;
return min_op(N, M);
if __name__ = = "__main__" :
N = 6
M = 24
op = min_operations(N, M);
if (op > = INF):
print ( - 1 )
else :
print (op)
|
C#
using System;
class GFG{
static int INF = ( int ) 1e7;
static int max_size = 100007;
static int []dp = new int [max_size];
static int min_op( int cur, int M)
{
if (cur > M)
return INF;
if (cur == M)
return 0;
if (dp[cur] != -1)
return dp[cur];
int op = INF;
for ( int i = 2; i * i <= cur; i++)
{
if (cur % i == 0)
{
if (i % 2 == 0)
{
op = Math.Min(op, 1 +
min_op(cur + i, M));
}
if ((cur / i) != i &&
(cur / i) % 2 == 0)
{
op = Math.Min(op, 1 +
min_op(cur +
(cur / i), M));
}
}
}
return dp[cur] = op;
}
static int min_operations( int N,
int M)
{
for ( int i = N; i <= M; i++)
{
dp[i] = -1;
}
return min_op(N, M);
}
public static void Main(String[] args)
{
int N = 6, M = 24;
int op = min_operations(N, M);
if (op >= INF)
Console.Write( "-1" );
else
Console.Write(op + "\n" );
}
}
|
Javascript
<script>
var INF = 10000000;
var max_size = 100007;
var dp = Array(max_size);
function min_op( cur, M)
{
if (cur > M)
return INF;
if (cur == M)
return 0;
if (dp[cur] != -1)
return dp[cur];
var op = INF;
for ( var i = 2; i * i <= cur; i++) {
if (cur % i == 0) {
if (i % 2 == 0) {
op = Math.min(op, 1 + min_op(cur + i, M));
}
if ((cur / i) != i && (cur / i) % 2 == 0) {
op = Math.min(op,
1 + min_op(cur + (cur / i), M));
}
}
}
return dp[cur] = op;
}
function min_operations(N, M)
{
for ( i = N; i <= M; i++) {
dp[i] = -1;
}
return min_op(N, M);
}
var N = 6, M = 24;
var op = min_operations(N, M);
if (op >= INF)
document.write( "-1" );
else
document.write( op + "<br>" );
</script>
|
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;
const int INF = 1e7;
int min_operations( int N, int M)
{
int dp[M+1];
for ( int i = 0; i <= M; i++) {
dp[i] = INF;
}
dp[N] = 0;
for ( int i = N; i < M; i++) {
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) {
dp[next] = min(dp[next], dp[i] + 1);
}
}
if ((i / j) != j && (i / j) % 2 == 0) {
int next = i + (i / j);
if (next <= M) {
dp[next] = min(dp[next], dp[i] + 1);
}
}
}
}
}
if (dp[M] >= INF) {
cout << "-1\n" ;
} else {
cout << dp[M] << "\n" ;
}
}
int main()
{
int N = 6, M = 24;
min_operations(N, M);
return 0;
}
|
Java
import java.util.*;
class Main {
static final int INF = 10000000 ;
static int minOperations( int N, int M)
{
int [] dp = new int [M + 1 ];
Arrays.fill(dp, INF);
dp[N] = 0 ;
for ( int i = N; i < M; i++) {
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) {
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) {
dp[next] = Math.min(dp[next],
dp[i] + 1 );
}
}
}
}
}
if (dp[M] >= INF) {
System.out.println( "-1" );
}
else {
System.out.println(dp[M]);
}
return 0 ;
}
public static void main(String[] args)
{
int N = 6 , M = 24 ;
minOperations(N, M);
}
}
|
Python3
INF = 10 * * 7
def min_operations(N: int , M: int ) - > None :
dp = [INF] * (M + 1 )
dp[N] = 0
for i in range (N, M):
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:
dp[ next ] = min (dp[ next ], dp[i] + 1 )
if (i / / j) ! = j and (i / / j) % 2 = = 0 :
next = i + (i / / j)
if next < = M:
dp[ next ] = min (dp[ next ], dp[i] + 1 )
if dp[M] > = INF:
print ( "-1" )
else :
print (dp[M])
if __name__ = = '__main__' :
N, M = 6 , 24
min_operations(N, M)
|
C#
using System;
public class MainClass
{
static readonly int INF = 10000000;
static int minOperations( int N, int M)
{
int [] dp = new int [M + 1];
Array.Fill(dp, INF);
dp[N] = 0;
for ( int i = N; i < M; i++)
{
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)
{
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)
{
dp[next] = Math.Min(dp[next],
dp[i] + 1);
}
}
}
}
}
if (dp[M] >= INF)
{
Console.WriteLine( "-1" );
}
else
{
Console.WriteLine(dp[M]);
}
return 0;
}
public static void Main( string [] args)
{
int N = 6, M = 24;
minOperations(N, M);
}
}
|
Javascript
const INF = 1e7;
function min_operations(N, M) {
let dp = Array(M+1).fill(INF);
dp[N] = 0;
for (let i = N; i < M; i++) {
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) {
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) {
dp[next] = Math.min(dp[next], dp[i] + 1);
}
}
}
}
}
if (dp[M] >= INF) {
console.log( "-1" );
} else {
console.log(dp[M]);
}
}
let N = 6, M = 24;
min_operations(N, M);
|
Time Complexity : O(M * sqrt(M))
Auxiliary Space: O(M)
Last Updated :
03 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...