Minimize operations to reduce N to 0 by replacing N by its divisor at each step
Given a positive integer N. Find the minimum number of operations needed to reduce N to 0 when N can reduced by its divisor at each operation.
Example:
Input: N = 5
Output: 4
Explanation:
Reduce 5 as 5-1=4.
Reduce 4 as 4-2=2.
Reduce 2 as 2-1=1.
Reduce 1 as 1-1=0.
Input: N = 8
Output: 4
Explanation:
Reduce 8 as 8-4=4.
Reduce 4 as 4-2=2.
Reduce 2 as 2-1=1.
Reduce 1 as 1-1=0.
Naive Approach:
One easy approach is to find highest divisor of N each time until N becomes 0.
Follow the below steps to solve this problem:
- Traverse until N becomes 0.
- Find the highest divisor of N and subtract from N.
- Count the number of iterations required for N to become 0 this way.
- Return the count calculated above as the final answer.
C++14
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll findElement(ll N)
{
for (ll i = 2; i * i <= N; i++) {
if (N % i == 0)
return N / i;
}
return 1;
}
ll minOperations(ll N)
{
if (N < 0)
return -1;
ll count = 0;
while (N) {
ll divisor = findElement(N);
N -= divisor;
count++;
}
return count;
}
int main()
{
ll N = 5;
cout << minOperations(N);
return 0;
}
|
Java
import java.io.*;
class GFG {
static long findElement( long N)
{
for ( long i = 2 ; i * i <= N; i++) {
if (N % i == 0 )
return N / i;
}
return 1 ;
}
static long minOperations( long N)
{
if (N < 0 )
return - 1 ;
long count = 0 ;
while (N > 0 ) {
long divisor = findElement(N);
N -= divisor;
count++;
}
return count;
}
public static void main (String[] args) {
long N = 5 ;
System.out.print(minOperations(N));
}
}
|
Python3
def findElement(N):
i = 2
while i * i < = N:
if N % i = = 0 :
return int (N / i)
i + = 1
return 1
def minOperations(N):
if N < 0 :
return - 1
count = 0
while N:
divisor = findElement(N)
N - = divisor
count + = 1
return count
N = 5
print (minOperations(N))
|
C#
using System;
class GFG {
static long findElement( long N)
{
for ( long i = 2; i * i <= N; i++) {
if (N % i == 0)
return N / i;
}
return 1;
}
static long minOperations( long N)
{
if (N < 0)
return -1;
long count = 0;
while (N > 0) {
long divisor = findElement(N);
N -= divisor;
count++;
}
return count;
}
public static void Main()
{
long N = 5;
Console.WriteLine(minOperations(N));
}
}
|
Javascript
<script>
const findElement = (N) => {
for (let i = 2; i * i <= N; i++) {
if (N % i == 0)
return parseInt(N / i);
}
return 1;
}
const minOperations = (N) => {
if (N < 0)
return -1;
let count = 0;
while (N) {
let divisor = findElement(N);
N -= divisor;
count++;
}
return count;
}
let N = 5;
document.write(minOperations(N));
</script>
|
Time Complexity: O(N^(3/2))
Auxiliary Space: O(1)
Efficient Approach: Above solution can be optimized using pre-computation using Sieve of Eratosthenes for smallest prime factor and modifying it a bit for storing highest factor of N.
Follow the below steps to solve this problem:
- Precompute sieve using Sieve of Eratosthenes for least prime factor of numbers till N
- Modify above sieve by storing 1 for all zero values else i/sieve[i] for every i-th value
- Traverse until N becomes 0.
- Subtract sieve[N] for every iteration of N.
- Count the number of iterations required for N to become 0 this way.
- Return the count calculated above as the final answer.
C++14
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX 10000001
ll sieve[MAX];
void makeSieve()
{
ll i, j;
sieve[0] = 0;
sieve[1] = 1;
for (i = 2; i < MAX; i++)
sieve[i] = 0;
for (i = 2; i * i <= MAX; i++) {
if (!sieve[i]) {
sieve[i] = i;
for (j = i * i; j < MAX; j += i)
if (!sieve[j])
sieve[j] = i;
}
}
for (i = 2; i < MAX; i++) {
if (!sieve[i])
sieve[i] = 1;
else
sieve[i] = i / sieve[i];
}
}
ll minOperations(ll& N)
{
if (N < 0)
return -1;
ll count = 0;
makeSieve();
while (N) {
N -= sieve[N];
count++;
}
return count;
}
int main()
{
ll N = 8;
cout << minOperations(N);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int MAX= 10000001 ;
static int [] sieve = new int [MAX];
static void makeSieve()
{
int i, j;
sieve[ 0 ] = 0 ;
sieve[ 1 ] = 1 ;
for (i = 2 ; i < MAX; i++)
sieve[i] = 0 ;
for (i = 2 ; i * i <= MAX; i++) {
if (sieve[i]== 0 ) {
sieve[i] = i;
for (j = i * i; j < MAX; j += i)
if (sieve[j]== 0 )
sieve[j] = i;
}
}
for (i = 2 ; i < MAX; i++) {
if (sieve[i]== 0 )
sieve[i] = 1 ;
else
sieve[i] = i / sieve[i];
}
}
static int minOperations( int N)
{
if (N < 0 )
return - 1 ;
int count = 0 ;
makeSieve();
while (N != 0 ) {
N -= sieve[N];
count++;
}
return count;
}
public static void main(String[] args)
{
int N = 8 ;
System.out.print(minOperations(N));
}
}
|
Python3
MAX = 10000001
def makeSieve():
sieve = [ 0 ] * MAX
sieve[ 1 ] = 1
for i in range ( 2 , 1 + int ( MAX * * 0.5 )):
if not sieve[i]:
sieve[i] = i
for j in range (i * * 2 , MAX ):
if not sieve[j]:
sieve[j] = i
for i in range ( 2 , MAX ):
if not sieve[i]:
sieve[i] = 1
else :
sieve[i] = (i / / sieve[i])
return sieve
def minOperations(N):
if N < 0 :
return - 1
count = 0
sieve = makeSieve()
while N > 0 :
N - = (sieve[N])
count + = 1
return count
N = 8
print (minOperations(N))
|
C#
using System;
class GFG{
static int MAX= 10000001;
static int [] sieve = new int [MAX];
static void makeSieve()
{
int i, j;
sieve[0] = 0;
sieve[1] = 1;
for (i = 2; i < MAX; i++)
sieve[i] = 0;
for (i = 2; i * i <= MAX; i++) {
if (sieve[i]==0) {
sieve[i] = i;
for (j = i * i; j < MAX; j += i)
if (sieve[j]==0)
sieve[j] = i;
}
}
for (i = 2; i < MAX; i++) {
if (sieve[i]==0)
sieve[i] = 1;
else
sieve[i] = i / sieve[i];
}
}
static int minOperations( int N)
{
if (N < 0)
return -1;
int count = 0;
makeSieve();
while (N != 0) {
N -= sieve[N];
count++;
}
return count;
}
static public void Main (){
int N = 8;
Console.Write(minOperations(N));
}
}
|
Javascript
<script>
let MAX = 10000001
let sieve= new Array(MAX);
function makeSieve()
{
let i, j;
sieve[0] = 0;
sieve[1] = 1;
for (i = 2; i < MAX; i++)
sieve[i] = 0;
for (i = 2; i * i <= MAX; i++) {
if (!sieve[i]) {
sieve[i] = i;
for (j = i * i; j < MAX; j += i)
if (!sieve[j])
sieve[j] = i;
}
}
for (i = 2; i < MAX; i++) {
if (!sieve[i])
sieve[i] = 1;
else
sieve[i] = i / sieve[i];
}
}
function minOperations(N)
{
if (N < 0)
return -1;
let count = 0;
makeSieve();
while (N) {
N -= sieve[N];
count++;
}
return count;
}
let N = 8;
document.write(minOperations(N));
</script>
|
Time Complexity: O(N * log(log N)
Auxiliary Space: O(MAX), where MAX is the limit for sieve (here MAX = 10000001).
Last Updated :
04 May, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...