📌  相关文章
📜  使每个元素大于或等于K所需的最少操作

📅  最后修改于: 2021-04-22 02:36:26             🧑  作者: Mango

给定长度为N的数组。任务是将其转换为所有元素均大于或等于K的序列。唯一允许的操作是取序列中的两个最小元素,并用其LCM替换它们。找到所需的最少操作数。
如果不可能得到这样的数组,则打印-1。
例子:

方法:

  • 这个想法是使用一个优先级队列(最小堆),它可以在log(N)时间内处理删除和插入操作。
  • 当优先级队列中的元素数小于2时,将出现不可能的情况。在这种情况下,答案等于-1。
  • 否则,请从队列顶部获取两个元素,并用其LCM替换它。
  • 这样做直到队列顶部的最小数字小于K。

下面是上述方法的实现:

C++
// C++ implementation of above approach
#include 
using namespace std;
 
// C++ function to get
// minimum operation needed
int FindMinOperation(int a[], int n, int k)
{
 
    // The priority queue holds a minimum
    // element in the top position
    priority_queue,
                              greater > Q;
 
    for (int i = 0; i < n; i++)
 
        // push value one by one
        // from the given array
        Q.push(a[i]);
  
    // store count of minimum operation needed
    int ans = 0;
 
    while (1) {
 
        // All elements are now >= k
        if (Q.top() >= k)
            break;
 
        // It is impossible to make as there are
        // no sufficient elements available
        if (Q.size() < 2)
            return -1;
 
        // Take two smallest elements and
        // replace them by their LCM
        // first smallest element
        int x = Q.top();
        Q.pop();
 
        // Second smallest element
        int y = Q.top();
        Q.pop();
 
        int z = (x * y) / __gcd(x, y);
        Q.push(z);
 
        // Increment the count
        ans++;
    }
 
    return ans;
}
 
// Driver Code
int main()
{
 
    int a[] = { 3, 5, 7, 6, 8 };
    int k = 8;
    int n = sizeof(a) / sizeof(a[0]);
 
    cout << FindMinOperation(a, n, k);
}


Java
// Java implementation of above approach
import java.util.PriorityQueue;
 
class GFG
{
 
    // Function to calculate gcd of two numbers
    static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
 
    // Java function to get
    // minimum operation needed
    static int FindMinOperation(int[] a, int n, int k)
    {
 
        // The priority queue holds a minimum
        // element in the top position
        PriorityQueue Q = new PriorityQueue<>();
 
        for (int i = 0; i < n; i++)
 
            // push value one by one
            // from the given array
            Q.add(a[i]);
 
        // store count of minimum operation needed
        int ans = 0;
 
        while (true)
        {
 
            // All elements are now >= k
            if (Q.peek() >= k)
                break;
 
            // It is impossible to make as there are
            // no sufficient elements available
            if (Q.size() < 2)
                return -1;
 
            // Take two smallest elements and
            // replace them by their LCM
            // first smallest element
            int x = Q.peek();
            Q.poll();
 
            // Second smallest element
            int y = Q.peek();
            Q.poll();
 
            int z = (x * y) / gcd(x, y);
            Q.add(z);
 
            // Increment the count
            ans++;
        }
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] a = { 3, 5, 7, 6, 8 };
        int k = 8;
        int n = a.length;
        System.out.println(FindMinOperation(a, n, k));
    }
}
 
// This code is contributed by
// sanjeev2552


Python3
# Python3 implementation of above approach
 
# Function to calculate gcd of two numbers
def gcd(a, b) :
 
    if (a == 0) :
      return b
    return gcd(b % a, a)
     
# function to get 
# minimum operation needed
def FindMinOperation(a, n, k) :
     
    # The priority queue holds a minimum
    # element in the top position
    Q = []
    for i in range(0, n) :
     
      # push value one by one
      # from the given array
      Q.append(a[i])
    Q.sort()
     
    # store count of minimum operation needed
    ans = 0
    while (True) :
     
      # All elements are now >= k
      if (Q[0] >= k) :
        break
     
      # It is impossible to make as there are
      # no sufficient elements available
      if (len(Q) < 2) :
        return -1
     
      # Take two smallest elements and 
      # replace them by their LCM
      # first smallest element
      x = Q[0] 
      Q.pop(0)
     
      # Second smallest element
      y = Q[0] 
      Q.pop(0)
      z = (x * y) // gcd(x, y)
      Q.append(z)
      Q.sort()
     
      # Increment the count
      ans += 1 
  
    return ans
     
  # Driver code
a = [ 3, 5, 7, 6, 8 ]
k = 8
n = len(a)
 
print(FindMinOperation(a, n, k))
 
# This code is contributed by divyesh0720219.


C#
// C# implementation of above approach
using System;
using System.Collections.Generic;
class GFG
{
 
  // Function to calculate gcd of two numbers
  static int gcd(int a, int b)
  {
    if (a == 0)
      return b;
    return gcd(b % a, a);
  }
 
  // C# function to get 
  // minimum operation needed
  static int FindMinOperation(int[] a, int n, int k)
  {
 
    // The priority queue holds a minimum
    // element in the top position
    List Q = new List();
    for (int i = 0; i < n; i++)
 
      // push value one by one
      // from the given array
      Q.Add(a[i]);
    Q.Sort();
 
    // store count of minimum operation needed
    int ans = 0; 
    while (true)
    {
 
      // All elements are now >= k
      if (Q[0] >= k)
        break;
 
      // It is impossible to make as there are
      // no sufficient elements available
      if (Q.Count < 2)
        return -1;
 
      // Take two smallest elements and 
      // replace them by their LCM
      // first smallest element
      int x = Q[0]; 
      Q.RemoveAt(0);
 
      // Second smallest element
      int y = Q[0]; 
      Q.RemoveAt(0);
      int z = (x * y) / gcd(x, y);
      Q.Add(z);
      Q.Sort();
 
      // Increment the count
      ans++; 
    }
    return ans;
  }
 
  // Driver code
  static void Main()
  {
    int[] a = { 3, 5, 7, 6, 8 };
    int k = 8;
    int n = a.Length;
 
    Console.WriteLine(FindMinOperation(a, n, k));
  }
}
 
// This code is contributed by divyeshrabadiya07.


Javascript


输出:
2

时间复杂度: O(NlogN)