给定数字N。您的任务是找到最小的数字S,以使N是S的因数! (S阶乘)。 N可以很大。
例子:
Input : 6
Output : 3
The value of 3! is 6
This is the smallest number which can have 6 as a factor.
Input : 997587429953
Output : 998957
If we calculate out 998957!,
we shall find that it is divisible by 997587429953.
Factors of 997587429953 are 998957 and 998629.
天真的方法
我们从1迭代到N,在每种情况下都计算阶乘。当我们找到能够将N作为因子的阶乘时,我们将其输出。对于较大的N,将很难实现此方法,因为阶乘会变得非常大。
时间复杂度:O(N ^ 2)
优化的朴素方法
而不是从1迭代到N,我们使用二进制搜索。这仍然是一种不好的方法,因为我们仍在尝试计算N!
时间复杂度O(N log N)
最佳解决方案
我们可以首先计算N的所有素数。然后,我们将问题简化为找到具有N的所有素数的阶乘,至少是它们在N中出现的次数。然后我们对从1到N的元素进行二元搜索我们可以利用勒让德公式来检查数字的阶乘是否具有相同的素数。然后,我们找到最小的此类数字。
C++
// Program to find factorial that N belongs to
#include
using namespace std;
#define ull unsigned long long
// Calculate prime factors for a given number
map primeFactors(ull num)
{
// Container for prime factors
map ans;
// Iterate from 2 to i^2 finding all factors
for (ull i = 2; i * i <= num; i++)
{
while (num % i == 0)
{
num /= i;
ans[i]++;
}
}
// If we still have a remainder
// it is also a prime factor
if (num > 1)
ans[num]++;
return ans;
}
// Calculate occurrence of an element
// in factorial of a number
ull legendre(ull factor, ull num)
{
ull count = 0, fac2 = factor;
while (num >= factor)
{
count += num / factor;
factor *= fac2;
}
return count;
}
bool possible(map &factors, ull num)
{
// Iterate through prime factors
for (map::iterator it = factors.begin();
it != factors.end(); ++it)
{
// Check if factorial contains less
// occurrences of prime factor
if (legendre(it->first, num) < it->second)
return false;
}
return true;
}
// Function to binary search 1 to N
ull search(ull start, ull end, map &factors)
{
ull mid = (start + end) / 2;
// Prime factors are not in the factorial
// Increase the lowerbound
if (!possible(factors, mid))
return search(mid + 1, end, factors);
// We have reached smallest occurrence
if (start == mid)
return mid;
// Smaller factorial satisfying
// requirements may exist, decrease upperbound
return search(start, mid, factors);
}
// Calculate prime factors and search
ull findFact(ull num)
{
map factors = primeFactors(num);
return search(1, num, factors);
}
// Driver function
int main()
{
cout << findFact(6) << "n";
cout << findFact(997587429953) << "n";
return 0;
}
Java
// Java Program to find factorial that N belongs to
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
class Test
{
// Calculate prime factors for a given number
static HashMap primeFactors(long num)
{
// Container for prime factors
HashMap ans = new HashMap(){
@Override
public Integer get(Object key) {
if(containsKey(key)){
return super.get(key);
}
return 0;
}
};
// Iterate from 2 to i^2 finding all factors
for (long i = 2; i * i <= num; i++)
{
while (num % i == 0)
{
num /= i;
ans.put(i, ans.get(i)+1);
}
}
// If we still have a remainder
// it is also a prime factor
if (num > 1)
ans.put(num, ans.get(num)+1);;
return ans;
}
// Calculate occurrence of an element
// in factorial of a number
static long legendre(long factor, long num)
{
long count = 0, fac2 = factor;
while (num >= factor)
{
count += num / factor;
factor *= fac2;
}
return count;
}
static boolean possible(HashMap factors, long num)
{
Set s = factors.keySet();
// Iterate through prime factors
Iterator itr = s.iterator();
while (itr.hasNext()) {
long temp = itr.next();
// Check if factorial contains less
// occurrences of prime factor
if (legendre(temp, num) < factors.get(temp))
return false;
}
return true;
}
// Method to binary search 1 to N
static long search(long start, long end, HashMap factors)
{
long mid = (start + end) / 2;
// Prime factors are not in the factorial
// Increase the lowerbound
if (!possible(factors, mid))
return search(mid + 1, end, factors);
// We have reached smallest occurrence
if (start == mid)
return mid;
// Smaller factorial satisfying
// requirements may exist, decrease upperbound
return search(start, mid, factors);
}
// Calculate prime factors and search
static long findFact(long num)
{
HashMap factors = primeFactors(num);
return search(1, num, factors);
}
// Driver method
public static void main(String args[])
{
System.out.println(findFact(6));
System.out.println(findFact(997587429953L));
}
}
// This code is contributed by Gaurav Miglani
Python3
# Python Program to find factorial that N belongs to
# Calculate prime factors for a given number
def primeFactors(num):
# Container for prime factors
ans = dict()
i = 2
# Iterate from 2 to i^2 finding all factors
while(i * i <= num):
while (num % i == 0):
num //= i;
if i not in ans:
ans[i] = 0
ans[i] += 1
# If we still have a remainder
# it is also a prime factor
if (num > 1):
if num not in ans:
ans[num] = 0
ans[num] += 1
return ans;
# Calculate occurrence of an element
# in factorial of a number
def legendre(factor, num):
count = 0
fac2 = factor;
while (num >= factor):
count += num // factor;
factor *= fac2;
return count;
def possible(factors, num):
# Iterate through prime factors
for it in factors.keys():
# Check if factorial contains less
# occurrences of prime factor
if (legendre(it, num) < factors[it]):
return False;
return True;
# Function to binary search 1 to N
def search(start, end, factors):
mid = (start + end) // 2;
# Prime factors are not in the factorial
# Increase the lowerbound
if (not possible(factors, mid)):
return search(mid + 1, end, factors);
# We have reached smallest occurrence
if (start == mid):
return mid;
# Smaller factorial satisfying
# requirements may exist, decrease upperbound
return search(start, mid, factors);
# Calculate prime factors and search
def findFact(num):
factors = primeFactors(num);
return search(1, num, factors);
# Driver function
if __name__=='__main__':
print(findFact(6))
print(findFact(997587429953))
# This code is contributed by pratham76.
C#
// C# Program to find factorial that N belongs to
using System;
using System.Collections;
using System.Collections.Generic;
class Test
{
// Calculate prime factors for a given number
static Dictionary primeFactors(long num)
{
// Container for prime factors
Dictionary ans = new Dictionary();
// Iterate from 2 to i^2 finding all factors
for (long i = 2; i * i <= num; i++)
{
while (num % i == 0)
{
num /= i;
if(!ans.ContainsKey(i))
{
ans[i] = 0;
}
ans[i]++;
}
}
// If we still have a remainder
// it is also a prime factor
if (num > 1)
{
if(!ans.ContainsKey(num))
{
ans[num] = 0;
}
ans[num]++;
}
return ans;
}
// Calculate occurrence of an element
// in factorial of a number
static long legendre(long factor, long num)
{
long count = 0, fac2 = factor;
while (num >= factor)
{
count += num / factor;
factor *= fac2;
}
return count;
}
static bool possible(Dictionary factors, long num)
{
foreach (int itr in factors.Keys)
{
// Check if factorial contains less
// occurrences of prime factor
if (legendre(itr, num) < factors[itr])
return false;
}
return true;
}
// Method to binary search 1 to N
static long search(long start, long end, Dictionary factors)
{
long mid = (start + end) / 2;
// Prime factors are not in the factorial
// Increase the lowerbound
if (!possible(factors, mid))
return search(mid + 1, end, factors);
// We have reached smallest occurrence
if (start == mid)
return mid;
// Smaller factorial satisfying
// requirements may exist, decrease upperbound
return search(start, mid, factors);
}
// Calculate prime factors and search
static long findFact(long num)
{
Dictionary factors = primeFactors(num);
return search(1, num, factors);
}
// Driver method
public static void Main()
{
Console.WriteLine(findFact(6));
Console.WriteLine(findFact(997587429953L));
}
}
// This code is contributed by rutvik_56.
输出:
3
998957