给定一个长度为N的数组。任务是将它转换成一个序列,其中所有元素都大于或等于K 。唯一允许的操作是取序列中的两个最小元素并用它们的 LCM 替换它们。找出所需的最少操作次数。
如果不可能得到这样的数组,打印-1。
例子:
Input : N = 4, K = 3 , arr=[1 4 5 5]
Output : 1
LCM of 1 and 4 is 4, hence Replace (1,4) with 4.
Now the array becomes [4,4,5].
Every element in this array is greater than or equal to K.
No of operations required is equal to 1.
Input : N = 5, K = 8 , arr=[4,4,4,4,4]
Output : -1
It is not possible to convert the given array.
方法:
- 这个想法是使用一个优先级队列(最小堆),它可以在 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)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。