📜  查找在1到M范围内最大化数组LCM的元素

📅  最后修改于: 2021-04-23 16:48:48             🧑  作者: Mango

给定大小为N的数组arr ,其中包含范围为[1,M]的数字,任务是找到范围为[1,M]的元素,该元素可使LCM最大化。

例子:

天真的方法:

  • 计算给定阵列的LCM。
  • 将数组中不存在的[1,M]范围内的每个元素相加后,计算LCM并返回最大的元素。

高效方法:

  • 使用筛子预先计算直到1000的素数。
  • 存储给定阵列LCM的每个素数的频率。
  • 从值[1,M]进行迭代,对于数组中不存在的每个值,计算该数量的质数因子频率与给定数组的LCM的频率差
  • 返回提供最大积的元素。

下面的代码是上述方法的实现:

C++
// C++ program to find the element
// to be added to maximize the LCM
  
#include 
using namespace std;
  
// Vector which stores the prime factors
// of all the numbers upto 10000
vector primeFactors[10001];
set s;
  
// Function which finds prime
// factors using sieve method
void findPrimeFactors()
{
  
    // Boolean array which stores
    // true if the index is prime
    bool primes[10001];
    memset(primes, true, sizeof(primes));
  
    // Sieve of Eratosthenes
    for (int i = 2; i < 10001; i++) {
  
        if (primes[i]) {
            for (int j = i; j < 10001; j += i) {
  
                if (j != i) {
                    primes[j] = false;
                }
                primeFactors[j].push_back(i);
            }
        }
    }
}
  
// Function which stores frequency of every
// prime factor of LCM of the initial array
void primeFactorsofLCM(int* frequecyOfPrimes,
                       int* arr, int n)
{
  
    for (int i = 0; i < n; i++) {
        for (auto a : primeFactors[arr[i]]) {
  
            int k = 0;
  
            // While the prime factor
            // divides the number
            while ((arr[i] % a) == 0) {
                arr[i] /= a;
                k++;
            }
  
            frequecyOfPrimes[a]
                = max(frequecyOfPrimes[a], k);
        }
    }
}
  
// Function which returns the element
// which should be added to array
int elementToBeAdded(int* frequecyOfPrimes, int m)
{
    int product = 1;
  
    // To store the final answer
    int ans = 1;
  
    for (int i = 2; i <= m; i++) {
  
        if (s.find(i) != s.end())
            continue;
  
        int j = i;
        int current = 1;
  
        for (auto a : primeFactors[j]) {
  
            int k = 0;
  
            // While the prime factor
            // divides the number
            while ((j % a) == 0) {
  
                j /= a;
                k++;
                if (k > frequecyOfPrimes[a]) {
                    current *= a;
                }
            }
        }
  
        // Check element which provides
        // the maximum product
        if (current > product) {
            product = current;
            ans = i;
        }
    }
    return ans;
}
  
void findElement(int* arr, int n, int m)
{
  
    for (int i = 0; i < n; i++)
        s.insert(arr[i]);
    int frequencyOfPrimes[10001] = { 0 };
    primeFactorsofLCM(frequencyOfPrimes, arr, n);
    cout << elementToBeAdded(frequencyOfPrimes, m)
         << endl;
}
  
// Driver code
int main()
{
    // Precomputing the prime factors
    // of all numbers upto 10000
    findPrimeFactors();
  
    int N = 5;
    int M = 9;
    int arr[] = { 2, 5, 3, 8, 1 };
  
    findElement(arr, N, M);
  
    return 0;
}


Java
// Java program to find the element 
// to be added to maximize the LCM 
import java.util.*;
  
class GFG{ 
  
// Vector which stores the prime factors 
// of all the numbers upto 10000 
static Vector []primeFactors = new Vector[10001]; 
static HashSet s = new HashSet(); 
  
// Function which finds prime 
// factors using sieve method 
static void findPrimeFactors() 
{ 
  
    // Boolean array which stores 
    // true if the index is prime 
    boolean []primes = new boolean[10001]; 
    Arrays.fill(primes, true); 
  
    // Sieve of Eratosthenes 
    for (int i = 2; i < 10001; i++) { 
  
        if (primes[i]) { 
            for (int j = i; j < 10001; j += i) { 
  
                if (j != i) { 
                    primes[j] = false; 
                } 
                primeFactors[j].add(i); 
            } 
        } 
    } 
} 
  
// Function which stores frequency of every 
// prime factor of LCM of the initial array 
static void primeFactorsofLCM(int []frequecyOfPrimes, 
                    int[] arr, int n) 
{ 
  
    for (int i = 0; i < n; i++) { 
        for (int a : primeFactors[arr[i]]) { 
  
            int k = 0; 
  
            // While the prime factor 
            // divides the number 
            while ((arr[i] % a) == 0) { 
                arr[i] /= a; 
                k++; 
            } 
  
            frequecyOfPrimes[a] 
                = Math.max(frequecyOfPrimes[a], k); 
        } 
    } 
} 
  
// Function which returns the element 
// which should be added to array 
static int elementToBeAdded(int []frequecyOfPrimes, int m) 
{ 
    int product = 1; 
  
    // To store the final answer 
    int ans = 1; 
  
    for (int i = 2; i <= m; i++) { 
  
        if (s.contains(i)) 
            continue; 
  
        int j = i; 
        int current = 1; 
  
        for (int a : primeFactors[j]) { 
  
            int k = 0; 
  
            // While the prime factor 
            // divides the number 
            while ((j % a) == 0) { 
  
                j /= a; 
                k++; 
                if (k > frequecyOfPrimes[a]) { 
                    current *= a; 
                } 
            } 
        } 
  
        // Check element which provides 
        // the maximum product 
        if (current > product) { 
            product = current; 
            ans = i; 
        } 
    } 
    return ans; 
} 
  
static void findElement(int[] arr, int n, int m) 
{ 
  
    for (int i = 0; i < n; i++) 
        s.add(arr[i]); 
    int frequencyOfPrimes[] = new int[10001]; 
    primeFactorsofLCM(frequencyOfPrimes, arr, n); 
    System.out.print(elementToBeAdded(frequencyOfPrimes, m) 
        +"\n"); 
} 
  
// Driver code 
public static void main(String[] args) 
{ 
    for (int i = 0; i < 10001; i++) 
        primeFactors[i] = new Vector();
    // Precomputing the prime factors 
    // of all numbers upto 10000 
    findPrimeFactors(); 
  
    int N = 5; 
    int M = 9; 
    int arr[] = { 2, 5, 3, 8, 1 }; 
  
    findElement(arr, N, M); 
}
} 
  
// This code is contributed by Rajput-Ji


C#
// C# program to find the element 
// to be added to maximize the LCM 
using System;
using System.Collections.Generic;
  
class GFG{ 
   
// List which stores the prime factors 
// of all the numbers upto 10000 
static List []primeFactors = new List[10001]; 
static HashSet s = new HashSet(); 
   
// Function which finds prime 
// factors using sieve method 
static void findPrimeFactors() 
{ 
   
    // Boolean array which stores 
    // true if the index is prime 
    bool []primes = new bool[10001]; 
    for (int i = 0; i < 10001; i++) 
        primes[i] = true;
   
    // Sieve of Eratosthenes 
    for (int i = 2; i < 10001; i++) { 
   
        if (primes[i]) { 
            for (int j = i; j < 10001; j += i) { 
   
                if (j != i) { 
                    primes[j] = false; 
                } 
                primeFactors[j].Add(i); 
            } 
        } 
    } 
} 
   
// Function which stores frequency of every 
// prime factor of LCM of the initial array 
static void primeFactorsofLCM(int []frequecyOfPrimes, 
                    int[] arr, int n) 
{ 
   
    for (int i = 0; i < n; i++) { 
        foreach (int a in primeFactors[arr[i]]) { 
   
            int k = 0; 
   
            // While the prime factor 
            // divides the number 
            while ((arr[i] % a) == 0) { 
                arr[i] /= a; 
                k++; 
            } 
   
            frequecyOfPrimes[a] 
                = Math.Max(frequecyOfPrimes[a], k); 
        } 
    } 
} 
   
// Function which returns the element 
// which should be added to array 
static int elementToBeAdded(int []frequecyOfPrimes, int m) 
{ 
    int product = 1; 
   
    // To store the readonly answer 
    int ans = 1; 
   
    for (int i = 2; i <= m; i++) { 
   
        if (s.Contains(i)) 
            continue; 
   
        int j = i; 
        int current = 1; 
   
        foreach (int a in primeFactors[j]) { 
   
            int k = 0; 
   
            // While the prime factor 
            // divides the number 
            while ((j % a) == 0) { 
   
                j /= a; 
                k++; 
                if (k > frequecyOfPrimes[a]) { 
                    current *= a; 
                } 
            } 
        } 
   
        // Check element which provides 
        // the maximum product 
        if (current > product) { 
            product = current; 
            ans = i; 
        } 
    } 
    return ans; 
} 
   
static void findElement(int[] arr, int n, int m) 
{ 
   
    for (int i = 0; i < n; i++) 
        s.Add(arr[i]); 
    int []frequencyOfPrimes = new int[10001]; 
    primeFactorsofLCM(frequencyOfPrimes, arr, n); 
    Console.Write(elementToBeAdded(frequencyOfPrimes, m) 
        +"\n"); 
} 
   
// Driver code 
public static void Main(String[] args) 
{ 
    for (int i = 0; i < 10001; i++) 
        primeFactors[i] = new List();
  
    // Precomputing the prime factors 
    // of all numbers upto 10000 
    findPrimeFactors(); 
   
    int N = 5; 
    int M = 9; 
    int []arr = { 2, 5, 3, 8, 1 }; 
   
    findElement(arr, N, M); 
}
} 
   
// This code is contributed by PrinciRaj1992


输出:
7

时间复杂度: O(N * log N + M * log M)