📌  相关文章
📜  使所有Array元素成为素数所需的最小更改

📅  最后修改于: 2021-04-21 22:24:14             🧑  作者: Mango

给定一个整数数组arr [] ,任务是计算将每个数组元素转换为最接近的素数所需的最小更改数。
例子:

天真的方法:
遍历数组,对于每个数组元素,从arr [i] + 1开始找到其最右边的素数,从arr [i] – 1开始找到其最左边的素数。计算完后,计算它们与arr [i]的差并考虑较小的差异。所有这些差异的总和给出了期望的输出。

时间复杂度: O(N * maxi 2 ),其中maxi表示数组中的最大元素。

高效方法:
可以使用Eratosthenes筛子解决此问题。请按照以下步骤解决问题:

  • 从给定的数组中找到最大的元素。
  • maxi为数组中存在的最大元素。生成[1,2 * maxi]范围内的所有素数并存储它们。
  • 遍历数组,并使用lower_bound(例如x)为每个数组元素找到下一个更大质数的索引。
  • 计算arr [i]和素数[x]之间以及arr [i]和素数[x – 1]之间的绝对差。
  • 将两者中的最小值相加到ans
  • 遍历数组后,打印ans的最终值作为答案。

下面是上述方法的实现:

C++
// C++ Program to implement
// the above approach
#include 
using namespace std;
 
// Function to generate all primes
vector SieveOfEratosthenes(int n)
{
    bool prime[2 * n + 1];
    memset(prime, true, sizeof(prime));
 
    for (int p = 2; p * p <= 2 * n; p++) {
 
        // If p is a prime
        if (prime[p] == true) {
 
            // Mark all its multiples
            // as non-prime
            for (int i = p * p; i <= 2 * n;
                 i += p)
                prime[i] = false;
        }
    }
 
    vector primes;
 
    // Store all prime numbers
    for (int p = 2; p <= 2 * n; p++)
        if (prime[p])
            primes.push_back(p);
 
    // Return the list of primes
    return primes;
}
 
// Function to calculate the
// minimum increments to
// convert every array elements
// to a prime
int minChanges(vector arr)
{
    int n = arr.size();
    int ans = 0;
 
    // Extract maximum element
    // of the given array
    int maxi = *max_element(arr.begin(),
                            arr.end());
 
    vector primes
        = SieveOfEratosthenes(maxi);
 
    for (int i = 0; i < n; i++) {
 
        // Extract the index which has
        // the next greater prime
        int x = lower_bound(primes.begin(),
                            primes.end(),
                            arr[i])
                - primes.begin();
 
        // Store the difference
        // between the prime and
        // the array element
        int minm = abs(primes[x]
                       - arr[i]);
 
        if (x > 1) {
            minm = min(minm,
                       abs(primes[x - 1]
                           - arr[i]));
        }
 
        ans += minm;
    }
    return ans;
}
 
// Driver Code
int main()
{
 
    vector arr
        = { 4, 25, 13, 6, 20 };
 
    cout << minChanges(arr);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to generate all primes
static ArrayList SieveOfEratosthenes(int n)
{
    boolean[] prime = new boolean[2 * n + 1];
    Arrays.fill(prime, true);
 
    for(int p = 2; p * p <= 2 * n; p++)
    {
         
        // If p is a prime
        if (prime[p] == true)
        {
             
            // Mark all its multiples
            // as non-prime
            for(int i = p * p;
                    i <= 2 * n; i += p)
                prime[i] = false;
        }
    }
     
    ArrayList primes = new ArrayList<>();
 
    // Store all prime numbers
    for(int p = 2; p <= 2 * n; p++)
        if (prime[p])
            primes.add(p);
 
    // Return the list of primes
    return primes;
}
 
// Function to calculate the
// minimum increments to
// convert every array elements
// to a prime
static int minChanges(int[] arr)
{
    int n = arr.length;
    int ans = 0;
 
    // Extract maximum element
    // of the given array
    int maxi = arr[0];
    for(int i = 1; i < arr.length; i++)
        maxi = Math.max(maxi, arr[i]);
         
    ArrayList primes = SieveOfEratosthenes(maxi);
 
    for(int i = 0; i < n; i++)
    {
         
        // Extract the index which has
        // the next greater prime
        int x = -1;
        for(int j = 0; j < primes.size(); j++)
        {
            if (arr[i] == primes.get(j))
            {
                x = j;
                break;
            }
            else if (arr[i] < primes.get(j))
            {
                x = j;
                break;
            }
        }
         
        // Store the difference
        // between the prime and
        // the array element
        int minm = Math.abs(primes.get(x) - arr[i]);
     
        if (x > 1)
        {
            minm = Math.min(minm,
                            Math.abs(primes.get(x - 1) -
                                     arr[i]));
        }
        ans += minm;
    }
    return ans;
}
 
// Driver code
public static void main (String[] args)
{
    int[] arr = { 4, 25, 13, 6, 20 };
     
    System.out.println(minChanges(arr));
}
}
 
// This code is contributed by offbeat


Python3
# Python program to implement
# the above approach
 
# Function to generate all primes
def SieveOfEratosthenes(n):
    prime = [True for i in range(2 * n + 1)]
    p = 2
    while(p * p <= 2 * n):
       
        # If p is a prime
        if(prime[p] == True):
             
            # Mark all its multiples
            # as non-prime
            i = p * p
            while(i <= n * 2):
                prime[i] = False
                i += p
        p += 1
    primes = []
     
    # Store all prime numbers
    for p in range(2, (2 * n) + 1):
        if(prime[p]):
            primes.append(p)
 
    # Return the list of primes
    return primes
 
# Function to calculate the
# minimum increments to
# convert every array elements
# to a prime
def minChanges(arr):
    n = len(arr)
    ans = 0
     
    # Extract maximum element
    # of the given array
    maxi = max(arr)
    primes = SieveOfEratosthenes(maxi)
    for i in range(n):
       
        # Extract the index which has
        # the next greater prime
        x = -1
        for j in range(len(primes)):
            if(arr[i] == primes[j]):
                x = j
                break
            elif(arr[i] < primes[j]):
                x = j
                break
                 
        # Store the difference
        # between the prime and
        # the array element
        minm = abs(primes[x] - arr[i])
 
        if(x > 1):
            minm = min(minm, abs(primes[x - 1]-arr[i]))
        ans += minm
    return ans
 
# Driver code
arr = [4, 25, 13, 6, 20]
print(minChanges(arr))
 
# This code is contributed by avanitrachhadiya2155


C#
// C# program to implement
// the above approach
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
 
// Function to generate all primes
static List SieveOfEratosthenes(int n)
{
    bool[] prime = new bool[2 * n + 1];
    Array.Fill(prime, true);
 
    for(int p = 2; p * p <= 2 * n; p++)
    {
         
        // If p is a prime
        if (prime[p] == true)
        {
             
            // Mark all its multiples
            // as non-prime
            for(int i = p * p; i <= 2 * n; i += p)
                prime[i] = false;
        }
    }  
    List primes = new List();
 
    // Store all prime numbers
    for(int p = 2; p <= 2 * n; p++)
        if (prime[p])
            primes.Add(p);
 
    // Return the list of primes
    return primes;
}
 
// Function to calculate the
// minimum increments to
// convert every array elements
// to a prime
static int minChanges(int[] arr)
{
    int n = arr.Length;
    int ans = 0;
 
    // Extract maximum element
    // of the given array
    int maxi = arr[0];
    for(int i = 1; i < arr.Length; i++)
        maxi = Math.Max(maxi, arr[i]);       
    List primes = SieveOfEratosthenes(maxi);
    for(int i = 0; i < n; i++)
    {
         
        // Extract the index which has
        // the next greater prime
        int x = -1;
        for(int j = 0; j < primes.Count; j++)
        {
            if (arr[i] == primes[j])
            {
                x = j;
                break;
            }
            else if (arr[i] < primes[j])
            {
                x = j;
                break;
            }
        }
         
        // Store the difference
        // between the prime and
        // the array element
        int minm = Math.Abs(primes[x]- arr[i]);
     
        if (x > 1)
        {
            minm = Math.Min(minm,
                            Math.Abs(primes[x - 1] -
                                     arr[i]));
        }
        ans += minm;
    }
    return ans;
}
 
// Driver code
public static void Main(string[] args)
{
    int[] arr = { 4, 25, 13, 6, 20 };
     
    Console.Write(minChanges(arr));
}
}
 
// This code is contributed by rutvik_56.


输出:
5

时间复杂度: O(log(log(N))+ O(NlogN)
辅助空间: O(N)