Divide N into K unique parts such that gcd of those parts is maximum
Given a positive integer N, the task is to divide it into K unique parts such that the sum of these parts is equal to the original number and the gcd of all the parts is maximum. Print the maximum gcd if such a division exists else print -1.
Examples:
Input: N = 6, K = 3
Output: 1
Only possible division with unique
elements are (1, 2, 3) and gcd(1, 2, 3) = 1.
Input: N = 18, K = 3
Output: 3
Naive approach: Find all the possible divisions of N and compute the maximum gcd of them. But this approach will take exponential time and space.
Efficient approach: Let the divisions of N be A1, A2……..AK
Now, it is known that gcd(a, b) = gcd(a, b, a + b) and hence, gcd(A1, A2….AK) = gcd(A1, A2….AK, A1 + A2…. + AK)
But A1 + A2…. + AK = N and hence, the gcd of the divisions will be one of the factors of N.
Let a be the factor of N which can be the possible answer:
Since a is the gcd, all the division will be the multiples of a and hence, for K unique Bi,
a * B1 + a * B2……. + a * BK = N
a * (B1 + B2…….+ BK) = N
Since all the Bi are unique,
B1 + B2…….+ BK ? 1 + 2 + 3 ….. + K
B1 + B2…….+ BK ? K * (K + 1) / 2
Hence, all the factors of N whose complementary factor is greater than or equal to K * (K + 1) / 2 can be one of the possible answers, and we have taken to the maximum of all the possible answers.
Below is the implementation of the above approach:
CPP
#include <bits/stdc++.h>
using namespace std;
int maxGCD( int N, int K)
{
int minSum = (K * (K + 1)) / 2;
if (N < minSum)
return -1;
int i = sqrt (N);
int res = 1;
while (i >= 1) {
if (N % i == 0) {
if (i >= minSum)
res = max(res, N / i);
if (N / i >= minSum)
res = max(res, i);
}
i--;
}
return res;
}
int main()
{
int N = 18, K = 3;
cout << maxGCD(N, K);
return 0;
}
|
Java
import java.io.*;
import java.lang.Math;
class GFG
{
static int maxGCD( int N, int K)
{
int minSum = (K * (K + 1 )) / 2 ;
if (N < minSum)
return - 1 ;
int i = ( int ) Math.sqrt(N);
int res = 1 ;
while (i >= 1 )
{
if (N % i == 0 )
{
if (i >= minSum)
res = Math.max(res, N / i);
if (N / i >= minSum)
res = Math.max(res, i);
}
i--;
}
return res;
}
public static void main (String[] args)
{
int N = 18 , K = 3 ;
System.out.println(maxGCD(N, K));
}
}
|
Python
from math import sqrt,ceil,floor
def maxGCD(N, K):
minSum = (K * (K + 1 )) / 2
if (N < minSum):
return - 1
i = ceil(sqrt(N))
res = 1
while (i > = 1 ):
if (N % i = = 0 ):
if (i > = minSum):
res = max (res, N / i)
if (N / i > = minSum):
res = max (res, i)
i - = 1
return res
N = 18
K = 3
print (maxGCD(N, K))
|
C#
using System;
class GFG
{
static int maxGCD( int N, int K)
{
int minSum = (K * (K + 1)) / 2;
if (N < minSum)
return -1;
int i = ( int ) Math.Sqrt(N);
int res = 1;
while (i >= 1)
{
if (N % i == 0)
{
if (i >= minSum)
res = Math.Max(res, N / i);
if (N / i >= minSum)
res = Math.Max(res, i);
}
i--;
}
return res;
}
public static void Main()
{
int N = 18, K = 3;
Console.WriteLine(maxGCD(N, K));
}
}
|
Javascript
<script>
function maxGCD(N , K) {
var minSum = (K * (K + 1)) / 2;
if (N < minSum)
return -1;
var i = parseInt( Math.sqrt(N));
var res = 1;
while (i >= 1) {
if (N % i == 0) {
if (i >= minSum)
res = Math.max(res, N / i);
if (N / i >= minSum)
res = Math.max(res, i);
}
i--;
}
return res;
}
var N = 18, K = 3;
document.write(maxGCD(N, K));
</script>
|
Time Complexity: O(N1/2)
Auxiliary Space: O(1)
Last Updated :
09 Nov, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...