Find minimum number K such that its factorial is multiple of N
Last Updated :
10 Aug, 2023
Given an integer N. The task is to find minimum K such that the factorial of K is multiple of N. (2 ≤ N ≤ 1012)
Examples:
Input: N = 30
Output: 5
Explanation: 5! % 30 = 120 % 30 = 0, Therefore 5 is the answer
Input: N = 280
Output: 7
Approach: To solve the problem follow the below idea:
- Binary Search can be used to solve this problem. Number of times number X! can be divided by Y is Z (for example 8 can be divided by 2, three times), Z = (X / Y) + (X / Y2) + (X / Y3) + (X / Y4) + ……………
- The idea is to first find all the prime divisors of N and their powers using a map data structure. Then, perform binary search to find the minimum value of K such that K! is a multiple of N and check if the mid value satisfies the condition or not by checking if every number that divides N compared with the mid value also divides mid, using the above formula.
- If the number of times N is divided by a prime divisor is greater than mid factorial, then mid factorial is not divisible by N, and return false else, returns true.
Below are the steps for the above approach:
- Declaring Hashmap mp[] to store divisors and their powers for number N.
- Declare low and high variables initially with values 2 and 1013.
- Write test() function that takes one parameter and returns a bool value whether the given number’s factorial is divisible by N.
- In the test, the function iterates all divisors of number N and checks whether those divisors also divide mid factorial which can be checked using the above number theory formula.
- Initialize the mid variable, mid = (low + high) / 2.
- Run a while loop till high – low > 1.
- check if the test function for the given mid value is true or not.
- if true set high to mid.
- else set low to mid + 1.
- After the while loop ends if the test function for low is true then return low else return high as the answer.
Below is the code for the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
#define int long long
bool test( int mid, map< int , int >& mp)
{
for ( auto & e : mp) {
int cnt = 0;
for ( int i = 1; i <= 30; i++) {
int temp = (mid / pow (e.first, i));
if (temp == 0)
break ;
cnt += temp;
}
if (e.second > cnt)
return 0;
}
return 1;
}
int findMinK( int N)
{
map< int , int > mp;
int count = 0;
while (!(N % 2)) {
N /= 2;
count++;
}
if (count)
mp[2] = count;
for ( int i = 3; i <= sqrt (N); i += 2) {
count = 0;
while (N % i == 0) {
count++;
N = N / i;
}
if (count)
mp[i] = count;
}
if (N > 2)
mp[N] = 1;
int low = 2, high = 1e13;
while (high - low > 1) {
int mid = (high + low) / 2;
if (test(mid, mp)) {
high = mid;
}
else {
low = mid + 1;
}
}
if (test(low, mp))
return low;
else
return high;
}
int32_t main()
{
int N = 30;
cout << findMinK(N) << endl;
return 0;
}
|
Java
import java.util.*;
class GFG {
static long MAX_VALUE = ( long )1e13;
static boolean test( long mid, Map<Long, Long> mp)
{
for (Map.Entry<Long, Long> e : mp.entrySet()) {
long cnt = 0 ;
for ( long i = 1 ; i <= 30 ; i++) {
long temp = ( long )Math.floor(
mid / Math.pow(e.getKey(), i));
if (temp == 0 )
break ;
cnt += temp;
}
if (e.getValue() > cnt)
return false ;
}
return true ;
}
static long findMinK( long N)
{
Map<Long, Long> mp = new HashMap<Long, Long>();
long count = 0 ;
while (N % 2 == 0 ) {
N /= 2 ;
count++;
}
if (count != 0 )
mp.put(( long ) 2 , count);
for ( long i = 3 ; i <= Math.sqrt(N); i += 2 ) {
count = 0 ;
while (N % i == 0 ) {
count++;
N /= i;
}
if (count != 0 )
mp.put(i, count);
}
if (N > 2 )
mp.put(N, ( long ) 1 );
long low = 2 , high = MAX_VALUE;
while (high - low > 1 ) {
long mid = (high + low) / 2 ;
if (test(mid, mp)) {
high = mid;
}
else {
low = mid + 1 ;
}
}
if (test(low, mp))
return low;
else
return high;
}
public static void main(String[] args)
{
int N = 30 ;
System.out.println(findMinK(N));
}
}
|
Python
import math
def test(mid, mp):
for e in mp.items():
cnt = 0
for i in range ( 1 , 31 ):
temp = mid / / math. pow (e[ 0 ], i)
if temp = = 0 :
break
cnt + = temp
if e[ 1 ] > cnt:
return False
return True
def findMinK(N):
mp = {}
count = 0
while N % 2 = = 0 :
N / / = 2
count + = 1
if count:
mp[ 2 ] = count
for i in range ( 3 , int (math.sqrt(N)) + 1 , 2 ):
count = 0
while N % i = = 0 :
count + = 1
N / / = i
if count:
mp[i] = count
if N > 2 :
mp[N] = 1
low, high = 2 , int ( 1e13 )
while high - low > 1 :
mid = (high + low) / / 2
if test(mid, mp):
high = mid
else :
low = mid + 1
if test(low, mp):
return low
else :
return high
if __name__ = = "__main__" :
N = 30
print (findMinK(N))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static bool Test( long mid, Dictionary< int , int > mp)
{
foreach ( var e in mp)
{
long cnt = 0;
for ( int i = 1; i <= 30; i++)
{
long temp = mid / ( long )Math.Pow(e.Key, i);
if (temp == 0)
break ;
cnt += temp;
}
if (e.Value > cnt)
return false ;
}
return true ;
}
static long FindMinK( int N)
{
Dictionary< int , int > mp = new Dictionary< int , int >();
int count = 0;
while (N % 2 == 0)
{
N /= 2;
count++;
}
if (count > 0)
mp[2] = count;
for ( int i = 3; i <= Math.Sqrt(N); i += 2)
{
count = 0;
while (N % i == 0)
{
count++;
N /= i;
}
if (count > 0)
mp[i] = count;
}
if (N > 2)
mp[N] = 1;
long low = 2, high = 10000000000000L;
while (high - low > 1)
{
long mid = (high + low) / 2;
if (Test(mid, mp))
{
high = mid;
}
else
{
low = mid + 1;
}
}
if (Test(low, mp))
return low;
else
return high;
}
static void Main( string [] args)
{
int N = 30;
Console.WriteLine(FindMinK(N));
Console.ReadLine();
}
}
|
Javascript
function test(mid, mp) {
for (let [key, value] of mp.entries()) {
let cnt = 0;
for (let i = 1; i <= 30; i++) {
let temp = Math.floor(mid / Math.pow(key, i));
if (temp === 0) break ;
cnt += temp;
}
if (value > cnt) return false ;
}
return true ;
}
function findMinK(N) {
let mp = new Map();
let count = 0;
while (N % 2 === 0) {
N /= 2;
count++;
}
if (count) mp.set(2, count);
for (let i = 3; i <= Math.sqrt(N); i += 2) {
count = 0;
while (N % i === 0) {
count++;
N /= i;
}
if (count) mp.set(i, count);
}
if (N > 2) mp.set(N, 1);
let low = 2,
high = 1e13;
while (high - low > 1) {
let mid = Math.floor((high + low) / 2);
if (test(mid, mp)) {
high = mid;
} else {
low = mid + 1;
}
}
if (test(low, mp)) return low;
else return high;
}
let N = 30;
console.log(findMinK(N));
|
Time Complexity: O(sqrt(N) * log2(K))
Auxiliary Space: O(1)
Related Articles:
Share your thoughts in the comments
Please Login to comment...