📜  数组中 k 个最小和 k 个最大合数的和和积

📅  最后修改于: 2021-10-28 02:05:30             🧑  作者: Mango

给定一个整数k和一个整数数组arr ,任务是找到数组中k 个最小和k 个最大合数的和和乘积。
假设数组中至少有k 个合数。

例子:

方法:

  1. 使用埃拉托色尼筛法生成一个布尔向量,其大小为数组中最大元素的大小,可用于检查数字是否为复合数。
  2. 还将01设置为素数,这样它们就不会被算作合数。
  3. 现在遍历数组并将所有合成的数字插入两个堆中,一个最小堆和一个最大堆。
  4. 现在,从最小堆中弹出前k 个元素,并取最小k 个合数的总和乘积
  5. 最大堆做同样的事情,得到最大k 个合数的乘积
  6. 最后,打印结果。

下面是上述方法的实现:

C++
// C++ program to find the sum and
// product of k smallest and k largest
// composite numbers in an array
#include 
using namespace std;
  
vector SieveOfEratosthenes(int max_val)
{
    // Create a boolean vector "prime[0..n]". A
    // value in prime[i] will finally be false
    // if i is Not a prime, else true.
    vector prime(max_val + 1, true);
    for (int p = 2; p * p <= max_val; p++) {
  
        // If prime[p] is not changed, then
        // it is a prime
        if (prime[p] == true) {
  
            // Update all multiples of p
            for (int i = p * 2; i <= max_val; i += p)
                prime[i] = false;
        }
    }
    return prime;
}
  
// Function that calculates the sum
// and product of k smallest and k
// largest composite numbers in an array
void compositeSumAndProduct(int arr[], int n, int k)
{
    // Find maximum value in the array
    int max_val = *max_element(arr, arr + n);
  
    // Use sieve to find all prime numbers
    // less than or equal to max_val
    vector prime = SieveOfEratosthenes(max_val);
  
    // Set 0 and 1 as primes so that
    // they don't get counted as 
    // composite numbers
    prime[0] = true;
    prime[1] = true;
  
    // Max Heap to store all the composite numbers
    priority_queue maxHeap;
  
    // Min Heap to store all the composite numbers
    priority_queue, greater> 
        minHeap;
  
    // Push all the composite numbers 
    // from the array to the heaps
    for (int i = 0; i < n; i++)
        if (!prime[arr[i]]) {
            minHeap.push(arr[i]);
            maxHeap.push(arr[i]);
        }
    long long int minProduct = 1
        , maxProduct = 1
        , minSum = 0
        , maxSum = 0;
    while (k--) {
  
        // Calculate the products
        minProduct *= minHeap.top();
        maxProduct *= maxHeap.top();
  
        // Calculate the sum
        minSum += minHeap.top();
        maxSum += maxHeap.top();
  
        // Pop the current minimum element
        minHeap.pop();
  
        // Pop the current maximum element
        maxHeap.pop();
    }
  
    cout << "Sum of k-minimum composite numbers is " 
         << minSum << "\n";
    cout << "Sum of k-maximum composite numbers is " 
         << maxSum << "\n";
    cout << "Product of k-minimum composite numbers is " 
         << minProduct << "\n";
    cout << "Product of k-maximum composite numbers is " 
         << maxProduct;
}
  
// Driver code
int main()
{
  
    int arr[] = { 4, 2, 12, 13, 5, 19 };
    int n = sizeof(arr) / sizeof(arr[0]);
  
    int k = 3;
  
    compositeSumAndProduct(arr, n, k);
  
    return 0;
}


Java
// Java program to find the sum and 
// product of k smallest and k largest 
// composite numbers in an array 
import java.util.*;
  
class GFG
{
    static boolean[] SieveOfEratosThenes(int max_val) 
    {
  
        // Create a boolean vector "prime[0..n]". A
        // value in prime[i] will finally be false
        // if i is Not a prime, else true.
        boolean[] prime = new boolean[max_val + 1];
        Arrays.fill(prime, true);
  
        for (int p = 2; p * p <= max_val; p++) 
        {
  
            // If prime[p] is not changed, then
            // it is a prime
            if (prime[p]) 
            {
  
                // Update all multiples of p
                for (int i = p * 2; i <= max_val; i += p)
                    prime[i] = false;
            }
        }
        return prime;
    }
  
    // Function that calculates the sum
    // and product of k smallest and k
    // largest composite numbers in an array
    static void compositeSumAndProduct(Integer[] arr, 
                                       int n, int k) 
    {
  
        // Find maximum value in the array
        int max_val = Collections.max(Arrays.asList(arr));
  
        // Use sieve to find all prime numbers
        // less than or equal to max_val
        boolean[] prime = SieveOfEratosThenes(max_val);
  
        // Set 0 and 1 as primes so that
        // they don't get counted as
        // composite numbers
        prime[0] = true;
        prime[1] = true;
  
        // Max Heap to store all the composite numbers
        PriorityQueue maxHeap = 
                  new PriorityQueue((x, y) -> y - x);
  
        // Min Heap to store all the composite numbers
        PriorityQueue minHeap = new PriorityQueue<>();
  
        // Push all the composite numbers
        // from the array to the heaps
        for (int i = 0; i < n; i++) 
        {
            if (!prime[arr[i]]) 
            {
                minHeap.add(arr[i]);
                maxHeap.add(arr[i]);
            }
        }
  
        long minProduct = 1, maxProduct = 1, 
                 minSum = 0, maxSum = 0;
        Integer lastMin = 0, lastMax = 0;
        while (k-- > 0) 
        {
            if (minHeap.peek() != null || 
                maxHeap.peek() != null)
            {
  
                // Calculate the products
                minProduct *= minHeap.peek();
                maxProduct *= maxHeap.peek();
  
                // Calculate the sum
                minSum += minHeap.peek();
                maxSum += maxHeap.peek();
  
                // Pop the current minimum element
                lastMin = minHeap.poll();
  
                // Pop the current maximum element
                lastMax = maxHeap.poll();
            } 
            else 
            {
  
                // when maxHeap or minHeap is exhausted 
                // then this consition will run
                minProduct *= lastMin;
                maxProduct *= lastMax;
  
                minSum += lastMin;
                maxSum += lastMax;
            }
        }
  
        System.out.println("Sum of k-minimum composite" + 
                                " numbers is " + minSum);
        System.out.println("Sum of k-maximum composite" + 
                                " numbers is " + maxSum);
        System.out.println("Product of k-minimum composite" + 
                                " numbers is " + minProduct);
        System.out.println("Product of k-maximum composite" + 
                                " numbers is " + maxProduct);
    }
  
    // Driver Code
    public static void main(String[] args)
    {
        Integer[] arr = { 4, 2, 12, 13, 5, 19 };
        int n = arr.length;
        int k = 3;
  
        compositeSumAndProduct(arr, n, k);
    }
}
  
// This code is contributed by
// sanjeev2552


输出:
Sum of k-minimum composite numbers is 28
Sum of k-maximum composite numbers is 20
Product of k-minimum composite numbers is 576
Product of k-maximum composite numbers is 192