Maximize the product of four factors of a Number
Last Updated :
31 Aug, 2022
Given an integer N, the task is to find the maximum product of A, B, C, D such that below conditions satisfy:
- N%A ==0 && N%B ==0 && N%C ==0 && N%D ==0.
- Maximize the product A*B*C*D where N = A+B+C+D.
If no solution exists, print ‘-1’ (without quotes).
Examples:
Input: N = 8
Output: 16
The divisors of 8 are {1, 2, 4, 8}.
The maximized product can be formed
by multiplying 2*2*2*2 = 16 as 2+2+2+2 = 8.
Input: N = 4
Output: 1
The divisors of 4 are {1, 2, 4}.
The maximized product can be formed
by multiplying 1*1*1*1 = 1 as 1+1+1+1 =4.
Naive Approach:
- Find out the factors of the given number and store them in a vector named factors in O(sqrt(n)) complexity.
- Initialize product = -1 and then we iterate over the factors vector to apply the brute force method to find the maximized product.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors;
void findFactors( int n)
{
for ( int i = 1; i * i <= n; i++) {
if (n % i == 0) {
if ((n / i) == i)
factors.push_back(i);
else {
factors.push_back(n / i);
factors.push_back(i);
}
}
}
}
int findProduct( int n)
{
int product = -1;
int si = factors.size();
for ( int i = 0; i < si; i++)
for ( int j = 0; j < si; j++)
for ( int k = 0; k < si; k++)
for ( int l = 0; l < si; l++) {
int s = factors[i] + factors[j]
+ factors[k] + factors[l];
if (s == n) {
int p = factors[i] * factors[j] * factors[k] * factors[l];
if (p > product)
product = p;
}
}
return product;
}
int main()
{
int n = 10;
findFactors(n);
cout << findProduct(n);
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
public class GFG {
static List< Integer> factors = new ArrayList<>( 10 );
static void findFactors( int n) {
for ( int i = 1 ; i * i <= n; i++) {
if (n % i == 0 ) {
if ((n / i) == i) {
factors.add(factors.size(), i);
} else {
factors.add(factors.size(), n / i);
factors.add(factors.size(), i);
}
}
}
}
static int findProduct( int n) {
int product = - 1 ;
int si = factors.size();
for ( int i = 0 ; i < si; i++) {
for ( int j = 0 ; j < si; j++) {
for ( int k = 0 ; k < si; k++) {
for ( int l = 0 ; l < si; l++) {
int s = factors.get(i) + factors.get(j)
+ factors.get(k) + factors.get(l);
if (s == n) {
int p = factors.get(i) * factors.get(j) * factors.get(k) *
factors.get(l);
if (p > product) {
product = p;
}
}
}
}
}
}
return product;
}
public static void main(String[] args) {
int n = 10 ;
findFactors(n);
System.out.println(findProduct(n));
}
}
|
Python3
from math import sqrt
factors = []
def findFactors(n):
for i in range ( 1 , int (sqrt(n)) + 1 , 1 ):
if (n % i = = 0 ):
if ((n / i) = = i):
factors.append(i)
else :
factors.append(n / i)
factors.append(i)
def findProduct(n):
product = - 1
si = len (factors)
for i in range (si):
for j in range (si):
for k in range (si):
for l in range (si):
s = (factors[i] + factors[j] +
factors[k] + factors[l])
if (s = = n):
p = (factors[i] * factors[j] *
factors[k] * factors[l])
if (p > product):
product = p
return product
if __name__ = = '__main__' :
n = 10
findFactors(n)
print ( int (findProduct(n)))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static List< int > factors = new List< int >(10);
static void findFactors( int n)
{
for ( int i = 1; i * i <= n; i++)
{
if (n % i == 0)
{
if ((n / i) == i)
{
factors.Insert(factors.Count, i);
}
else
{
factors.Insert(factors.Count, n / i);
factors.Insert(factors.Count, i);
}
}
}
}
static int findProduct( int n)
{
int product = -1;
int si = factors.Count;
for ( int i = 0; i < si; i++)
{
for ( int j = 0; j < si; j++)
{
for ( int k = 0; k < si; k++)
{
for ( int l = 0; l < si; l++)
{
int s = factors[i] + factors[j] +
factors[k] + factors[l];
if (s == n)
{
int p = factors[i] * factors[j] *
factors[k] * factors[l];
if (p > product)
{
product = p;
}
}
}
}
}
}
return product;
}
public static void Main(String[] args)
{
int n = 10;
findFactors(n);
Console.WriteLine(findProduct(n));
}
}
|
Javascript
<script>
let factors = [];
function findFactors(n)
{
for (let i = 1; i * i <= n; i++)
{
if (n % i == 0)
{
if ((n / i) == i) {
factors.push(i);
} else {
factors.push( n / i);
factors.push( i);
}
}
}
}
function findProduct(n)
{
let product = -1;
let si = factors.length;
for (let i = 0; i < si; i++) {
for (let j = 0; j < si; j++) {
for (let k = 0; k < si; k++) {
for (let l = 0; l < si; l++) {
let s = factors[i] + factors[j]
+ factors[k] + factors[l];
if (s == n) {
let p = factors[i] * factors[j] * factors[k] *
factors[l];
if (p > product) {
product = p;
}
}
}
}
}
}
return product;
}
let n = 10;
findFactors(n);
document.write(findProduct(n));
</script>
|
Time Complexity: O((no. of divisors)^4))
Auxiliary Space: O(sqrt(n))
Better Approach: Complexity can be slightly reduced by removing the 4th loop from the above-mentioned code and instead use a binary search to find the fourth factor. Since binary search only works when the list is sorted. So we need to sort the factors vector so that we can apply binary search to the problem.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > factors;
void findFactors( int n)
{
for ( int i = 1; i * i <= n; i++) {
if (n % i == 0) {
if ((n / i) == i) {
factors.push_back(i);
}
else {
factors.push_back(n / i);
factors.push_back(i);
}
}
}
}
int findProduct( int n)
{
int product = -1;
int si = factors.size();
for ( int i = 0; i < si; i++)
for ( int j = 0; j < si; j++)
for ( int k = 0; k < si; k++) {
int s = factors[i] + factors[j] + factors[k];
if (binary_search(factors.begin(), factors.end(), n - s)) {
int p = factors[i] * factors[j] * factors[k] * (n - s);
if (p > product)
product = p;
}
}
return product;
}
int main()
{
int n = 10;
findFactors(n);
sort(factors.begin(), factors.end());
cout << findProduct(n);
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class GFG {
static List< Integer> factors = new ArrayList<>();
static void findFactors( int n) {
for ( int i = 1 ; i * i <= n; i++) {
if (n % i == 0 ) {
if ((n / i) == i) {
factors.add(factors.size(), i);
} else {
factors.add(factors.size(), n/i);
factors.add(factors.size(), i);
}
}
}
}
static int findProduct( int n) {
int product = - 1 ;
int si = factors.size();
for ( int i = 0 ; i < si; i++) {
for ( int j = 0 ; j < si; j++) {
for ( int k = 0 ; k < si; k++) {
int s = factors.get(i) + factors.get(j) + factors.get(k);
if (Collections.binarySearch(factors, n - s) >= 0 ) {
int p = factors.get(i) * factors.get(j) * factors.get(k) * (n - s);
if (p > product) {
product = p;
}
}
}
}
}
return product;
}
public static void main(String[] args) {
int n = 10 ;
findFactors(n);
Collections.sort(factors);
System.out.println(findProduct(n));
}
}
|
Python3
factors = []
def findFactors(n):
for i in range ( 1 , n + 1 ):
if i * i > n:
break
if (n % i = = 0 ):
if ((n / i) = = i):
factors.append(i)
else :
factors.append(n / / i)
factors.append(i)
def findProduct(n):
product = - 1
si = len (factors)
for i in range (si):
for j in range (si):
for k in range (si):
s = factors[i] + factors[j] + factors[k]
if ((n - s) in factors):
p = factors[i] * factors[j] * \
factors[k] * (n - s)
if (p > product):
product = p
return product
n = 10
findFactors(n)
factors = sorted (factors)
print (findProduct(n))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static List< int > factors = new List< int >();
static void findFactors( int n)
{
for ( int i = 1; i * i <= n; i++)
{
if (n % i == 0)
{
if ((n / i) == i)
{
factors.Insert(factors.Count, i);
}
else
{
factors.Insert(factors.Count, n / i);
factors.Insert(factors.Count, i);
}
}
}
}
static int findProduct( int n)
{
int product = -1;
int si = factors.Count;
for ( int i = 0; i < si; i++)
{
for ( int j = 0; j < si; j++)
{
for ( int k = 0; k < si; k++)
{
int s = factors[i] + factors[j] + factors[k];
if (factors.BinarySearch(n - s) >= 0)
{
int p = factors[i] * factors[j] *
factors[k] * (n - s);
if (p > product)
{
product = p;
}
}
}
}
}
return product;
}
public static void Main(String[] args)
{
int n = 10;
findFactors(n);
factors.Sort();
Console.WriteLine(findProduct(n));
}
}
|
Javascript
<script>
let factors = [];
function findFactors(n)
{
for (let i = 1; i * i <= n; i++) {
if (n % i == 0) {
if ((n / i) == i) {
factors.push( i);
} else {
factors.push( n/i);
factors.push( i);
}
}
}
}
function findProduct(n)
{
let product = -1;
let si = factors.length;
for (let i = 0; i < si; i++) {
for (let j = 0; j < si; j++) {
for (let k = 0; k < si; k++) {
let s = factors[i] + factors[j] +
factors[k];
if ( factors.includes(n-s)) {
let p = factors[i] * factors[j] *
factors[k] * (n - s);
if (p > product) {
product = p;
}
}
}
}
}
return product;
}
let n = 10;
findFactors(n);
factors.sort( function (a,b){ return a-b;});
document.write(findProduct(n));
</script>
|
Time Complexity: O((no.of divisors)^3 * log(no. of divisors))
Efficient Approach: This is the returned maximized product upto first 40 natural numbers.
1-> -1, 2-> -1, 3-> -1, 4-> 1 , 5-> -1 , 6-> 4, 7-> -1, 8-> 16, 9-> -1, 10-> 20, 11-> -1 12-> 81, 13-> -1, 14-> -1 , 15-> -1, 16-> 256, 17-> -1 18-> 324, 19-> -1, 20-> 625, 21-> -1, 22-> -1, 23-> -1, 24-> 1296, 25-> -1, 26-> -1 27-> -1, 28-> 2401, 29-> -1, 30-> 2500, 31-> -1, 32-> 4096, 33-> -1, 34-> -1 35-> -1, 36-> 6561, 37-> -1, 38-> -1, 39-> -1, 40-> 10000, 41-> -1, 42-> 9604
If we closely try to observe the pattern we can find out the pattern is somewhat common in some cases.
For example:
- For every odd number there is no solution, hence returns -1.
- There is no solution for numbers less than 4.
- For every number which is divisible by 4 the solution is always in the form of (n/4)^4.
- the numbers like 4 which has factors {1, 2, 4} solution is 1 and (4/4)^4 = 1.
- the numbers like 8 which has factors {1, 2, 4, 8} solution is 16 ans (8/4)^4 = 16.
- For every number which is divisible by 6 the solution is always in the form of (n/3)^2 * (n/6)^2
- the numbers like 6 which has factors {1, 2, 3, 6} solution is 4 and (6/3)^2 * (6/6)^2 = 4.
- the numbers like 18 which has factors {1, 2, 3, 6, 9, 18} solution is 324 and (18/3)^2 * (18/6)^2 = 324.
- For every number which is divisible by 10 the solution is always in the form of (n/10) * (n/5)^2 * (n/2)
- the numbers like 10 which has factors {1, 2, 5, 10} solution is 20 and (10/10)*(10/5)^2 * (10/2) = 20.
- the numbers like 20 which has factors {1, 2, 5, 10, 25, 50} solution is 12500 and (50/10)*(50/5)^2 *(50/2) = 12500.
- For every other even number there is no solution the numbers like 14 and 22.
Note: We consider the lowest factor which divides the number first and we ignore the next consecutive divisors in order to calculate the max product. For example, 12 is divisible by 4 and 6 both. But we consider the least factor to calculate so we consider 4 as its divisor for calculation of product.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int modExp( int a, int b)
{
int result = 1;
while (b > 0) {
if (b & 1)
result = result * a;
a = a * a;
b /= 2;
}
return result;
}
int check( int num)
{
if (num & 1 || num < 3)
return -1;
else if (num % 4 == 0)
return modExp(num / 4, 4);
else if (num % 6 == 0)
return modExp(num / 3, 2) * modExp(num / 6, 2);
else if (num % 10 == 0)
return modExp(num / 5, 2) * (num / 10) * (num / 2);
else
return -1;
}
int main()
{
int num = 10;
cout << check(num);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
import java.lang.*;
class GFG
{
static int modExp( int a, int b)
{
int result = 1 ;
while (b > 0 )
{
if (b == 1 )
result = result * a;
a = a * a;
b /= 2 ;
}
return result;
}
static int check( int num)
{
if (num == 1 || num < 3 )
return - 1 ;
else if (num % 4 == 0 )
return modExp(num / 4 , 4 );
else if (num % 6 == 0 )
return modExp(num / 3 , 2 ) * modExp(num / 6 , 2 );
else if (num % 10 == 0 )
return modExp(num / 5 , 2 ) * (num / 10 ) * (num / 2 );
else
return - 1 ;
}
public static void main(String[] args)
{
int num = 10 ;
System.out.print(check(num));
}
}
|
Python3
def modExp( a, b):
result = 1
while (b > 0 ):
if ( int (b) & 1 ):
result = result * a
a = a * a
b / = 2
return result
def check( num):
if (num & 1 or num < 3 ):
return - 1
elif (num % 4 = = 0 ):
return modExp(num / 4 , 4 )
elif (num % 6 = = 0 ):
return modExp(num / 3 , 2 ) * modExp(num / 6 , 2 )
elif (num % 10 = = 0 ):
return modExp(num / 5 , 2 ) * (num / 10 ) * (num / 2 )
else :
return - 1
if __name__ = = '__main__' :
num = 10
print ( int (check(num)))
|
C#
using System;
public class GFG{
static int modExp( int a, int b)
{
int result = 1;
while (b > 0)
{
if (b == 1)
result = result * a;
a = a * a;
b /= 2;
}
return result;
}
static int check( int num)
{
if (num == 1 || num < 3)
return -1;
else if (num % 4 == 0)
return modExp(num / 4, 4);
else if (num % 6 == 0)
return modExp(num / 3, 2) * modExp(num / 6, 2);
else if (num % 10 == 0)
return modExp(num / 5, 2) * (num / 10) * (num / 2);
else
return -1;
}
static public void Main (){
int num = 10;
Console.WriteLine(check(num));
}
}
|
PHP
<?php
function modExp( $a , $b )
{
$result = 1;
while ( $b > 0)
{
if ( $b & 1)
$result = $result * $a ;
$a = $a * $a ;
$b /= 2;
}
return $result ;
}
function check( $num )
{
if ( $num & 1 || $num < 3)
return -1;
else if ( $num % 4 == 0)
return modExp( $num / 4, 4);
else if ( $num % 6 == 0)
return modExp( $num / 3, 2) *
modExp( $num / 6, 2);
else if ( $num % 10 == 0)
return modExp( $num / 5, 2) *
( $num / 10) * ( $num / 2);
else
return -1;
}
$num = 10;
echo check( $num );
?>
|
Javascript
<script>
function modExp(a, b)
{
let result = 1;
while (b > 0)
{
if (b == 1)
result = result * a;
a = a * a;
b = Math.floor(b / 2);
}
return result;
}
function check(num)
{
if (num == 1 || num < 3)
return -1;
else if (num % 4 == 0)
return modExp(Math.floor(num / 4), 4);
else if (num % 6 == 0)
return modExp(Math.floor(num / 3), 2) *
modExp(Math.floor(num / 6), 2);
else if (num % 10 == 0)
return modExp(Math.floor(num / 5), 2) *
Math.floor(num / 10) *
Math.floor(num / 2);
else
return -1;
}
let num = 10;
document.write(check(num));
</script>
|
Time Complexity: O(log N)
Share your thoughts in the comments
Please Login to comment...