最小可能整数 K,使得每个 Array 元素的 ceil 除以 K 时最多为 M
给定一个由N个正整数和一个正整数M组成的数组arr[] ,任务是找到最小的可能整数K ,使得ceil(arr[0]/K) + ceil(arr[1]/K) +… .+ ceil(arr[N – 1]/K)最多为 M 。
例子:
Input: arr[] = {4, 3, 2, 7}, M = 5
Output: 4
Explanation:
For K = 4, the value of ceil(4/4) + ceil(3/4) + ceil(2/4) + ceil(7/4) = 1 + 1 + 1 + 2 = 5. Therefore, print 5.
Input: arr[] = {1, 2, 3}, M = 4
Output: 2
方法:这个想法是使用二分搜索。从数组arr[]中将低值设置为1 ,将高值设置为最大值,并通过二进制搜索找到小于或等于M的K值。请按照以下步骤解决问题:
- 初始化变量,比如low = 1和high作为最大数组元素。
- 迭代 while 循环直到high – low > 1并执行以下任务:
- 通过mid = (low + high)/2更新 mid 的值。
- 遍历数组arr[]并通过假设mid为K找到ceil(arr[i]/K)的总和。
- 如果总和大于M ,则 将 high 的值更新为high = mid 。否则,将 low 的值更新为low = mid + 1 。
- 完成上述步骤后,如果总和最多为 M ,则打印low的值。否则,打印high的值。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to check if the sum of ceil
// values of the arr[] for the K value
// is at most M or not
bool isvalid(int arr[], int K, int N, int M)
{
// Stores the sum of ceil values
int sum = 0;
for (int i = 0; i < N; i++) {
// Update the sum
sum += (int)ceil(arr[i] * 1.0 / K);
}
// Return true if sum is less than
// or equal to M, false otherwise
return sum <= M;
}
// Function to find the smallest possible
// integer K such that ceil(arr[0]/K) +
// ceil(arr[1]/K) +....+ ceil(arr[N-1]/K)
// is less than or equal to M
int smallestValueForK(int arr[], int N, int M)
{
// Stores the low value
int low = 1;
// Stores the high value
int high = *max_element(arr, arr + N);
// Stores the middle value
int mid;
while (high - low > 1) {
// Update the mid value
mid = (high + low) / 2;
// Check if the mid value is K
if (!isvalid(arr, mid, N, M))
// Update the low value
low = mid + 1;
else
// Update the high value
high = mid;
}
// Check if low is K or high is K
// and return it
return isvalid(arr, low, N, M) ? low : high;
}
// Driver Code
int main()
{
int arr[] = { 4, 3, 2, 7 };
int N = sizeof(arr) / sizeof(arr[0]);
int M = 5;
cout << smallestValueForK(arr, N, M);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG {
// Function to check if the sum of ceil
// values of the arr[] for the K value
// is at most M or not
static boolean isvalid(int[] arr, int K, int N, int M)
{
// Stores the sum of ceil values
int sum = 0;
for (int i = 0; i < N; i++) {
// Update the sum
sum += Math.ceil(arr[i] * 1.0 / K);
}
// Return true if sum is less than
// or equal to M, false otherwise
return sum <= M;
}
// Function to find the smallest possible
// integer K such that ceil(arr[0]/K) +
// ceil(arr[1]/K) +....+ ceil(arr[N-1]/K)
// is less than or equal to M
static int smallestValueForK(int[] arr, int N, int M)
{
// Stores the low value
int low = 1;
// Stores the high value
int high = arr[0];
//Loop through the array
for (int i = 0; i < arr.length; i++) {
//Compare elements of array with max
if(arr[i] > high)
high = arr[i];
}
// Stores the middle value
int mid;
while (high - low > 1) {
// Update the mid value
mid = (high + low) / 2;
// Check if the mid value is K
if (isvalid(arr, mid, N, M)==false)
// Update the low value
low = mid + 1;
else
// Update the high value
high = mid;
}
// Check if low is K or high is K
// and return it
return isvalid(arr, low, N, M) ? low : high;
}
// Driver Code
public static void main(String args[])
{
int arr[] = { 4, 3, 2, 7 };
int N = arr.length;
int M = 5;
System.out.print(smallestValueForK(arr, N, M));
}
}
// This code is contributed by SURENDRA_GANGWAR.
Python3
# python program for the above approach
import math
# Function to check if the sum of ceil
# values of the arr[] for the K value
# is at most M or not
def isvalid(arr, K, N, M):
# Stores the sum of ceil values
sum = 0
for i in range(0, N):
# Update the sum
sum += math.ceil(arr[i] * 1.0 / K)
# Return true if sum is less than
# or equal to M, false otherwise
return sum <= M
# Function to find the smallest possible
# integer K such that ceil(arr[0]/K) +
# ceil(arr[1]/K) +....+ ceil(arr[N-1]/K)
# is less than or equal to M
def smallestValueForK(arr, N, M):
# Stores the low value
low = 1
# Stores the high value
high = arr[0]
for i in range(1, len(arr)):
high = max(high, arr[i])
# Stores the middle value
mid = 0
while (high - low > 1):
# Update the mid value
mid = (high + low) // 2
# Check if the mid value is K
if (not isvalid(arr, mid, N, M)):
# Update the low value
low = mid + 1
else:
# Update the high value
high = mid
# Check if low is K or high is K
# and return it
if(isvalid(arr, low, N, M)):
return low
else:
return high
# Driver Code
if __name__ == "__main__":
arr = [4, 3, 2, 7]
N = len(arr)
M = 5
print(smallestValueForK(arr, N, M))
# This code is contributed by rakeshsahni
C#
// C# program for the above approach
using System;
using System.Linq;
class GFG {
// Function to check if the sum of ceil
// values of the arr[] for the K value
// is at most M or not
static bool isvalid(int[] arr, int K, int N, int M)
{
// Stores the sum of ceil values
int sum = 0;
for (int i = 0; i < N; i++) {
// Update the sum
sum += (int)Math.Ceiling(arr[i] * 1.0 / K);
}
// Return true if sum is less than
// or equal to M, false otherwise
return sum <= M;
}
// Function to find the smallest possible
// integer K such that ceil(arr[0]/K) +
// ceil(arr[1]/K) +....+ ceil(arr[N-1]/K)
// is less than or equal to M
static int smallestValueForK(int[] arr, int N, int M)
{
// Stores the low value
int low = 1;
// Stores the high value
int high = arr.Max();
// Stores the middle value
int mid;
while (high - low > 1) {
// Update the mid value
mid = (high + low) / 2;
// Check if the mid value is K
if (!isvalid(arr, mid, N, M))
// Update the low value
low = mid + 1;
else
// Update the high value
high = mid;
}
// Check if low is K or high is K
// and return it
return isvalid(arr, low, N, M) ? low : high;
}
// Driver Code
public static void Main()
{
int[] arr = { 4, 3, 2, 7 };
int N = arr.Length;
int M = 5;
Console.WriteLine(smallestValueForK(arr, N, M));
}
}
// This code is contributed by ukasp.
Javascript
输出:
4
时间复杂度: O(N*log N)
辅助空间: O(1)