Given an array arr[] consisting of heights of N chocolate bars, the task is to find the maximum height at which the horizontal cut is made to all the chocolates such that the sum remaining amount of chocolate is at least K.
Examples:
Input: K = 7, arr[] = [15, 20, 8, 17]
Output: 15
Explanation:
Suppose a cut is made at height 8:
-> chocolate taken from 1st chocolate bar = 15 – 8 =7
-> chocolate taken from 2nd chocolate bar = 20 – 8 =12
-> chocolate taken from 3rd chocolate bar = 8 – 8 = 0
-> chocolate taken from 4th chocolate bar = 17 – 8 = 9
=> Total chocolate wasted = (7 + 12 + 0 + 9) – K = 28 – 7 = 21
Suppose a cut is made at height 15:
-> chocolate taken from 1st chocolate bar = 15 – 15 = 0
-> chocolate taken from 2nd chocolate bar = 20 – 15 = 5
-> 3rd chocolate bar wont be chosen as it is less than 15
-> chocolate taken from 4th chocolate bar = 17 – 15 = 2
=> Total chocolate wasted = (0 + 5 + 2) – K = 7 – 7 = 0
Therefore when we take chocolate of height 15 then chocolate wasted is minimum. Therefore 15 is the answer.

Input: K = 12, arr[] = [30, 25, 22, 17, 20]
Output: 21
Explanation:

After a cut at height 18, the chocolate removed is 25 and chocolate wastage is (25 – 12) = 13 units. But if the cut is made at height 21 is made then 14 units of chocolate is removed and the wastage is (14 – 12) = 2 which is the least, hence 21 is the answer
Approach: The given problem can be solved based on Binary Search.
The idea is to perform the Binary Search over then range [0, max element of the array] and find that value in the range, say M, such that the sum of remaining chocolate after making the horizontal cut at M gives minimum difference with K.
Follow the steps below to solve the given problem:
- Initialize two variables, say low and high as 0 and the maximum array element respectively.
- Iterate until low <= high and perform the following steps:
- Find the value of mid as (low + high)/2.
- Find the sum of remaining chocolates after making the horizontal cut at height mid as M.
- If the value of M is less than K, then update the value of high as (mid – 1). Otherwise, update the value of low as (mid + 1).
- After performing the above steps, print the value as high as the resultant maximum height that must be cut.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int cal(vector< int > arr, int mid)
{
int chocolate = 0;
for ( auto i : arr) {
if (i >= mid)
chocolate += i - mid;
}
return chocolate;
}
int maximumCut(vector< int > arr, int K)
{
int low = 0;
int high = *max_element(arr.begin(), arr.end());
while (low <= high) {
int mid = (low + high) / 2;
int chocolate = cal(arr, mid);
if (chocolate == K)
return mid;
else if (chocolate < K)
high = mid - 1;
else {
low = mid + 1;
if (mid > high)
high = mid;
}
}
return high;
}
int main()
{
int N = 4;
int K = 7;
vector< int > arr{ 15, 20, 8, 17 };
cout << (maximumCut(arr, K));
}
|
Java
import java.util.*;
import java.util.Arrays;
class GFG {
static int cal( int arr[], int mid)
{
int chocolate = 0 ;
for ( int i = 0 ; i < arr.length; i++) {
if (arr[i] >= mid)
chocolate += arr[i] - mid;
}
return chocolate;
}
static int maximumCut( int arr[], int K)
{
int low = 0 ;
int high = Arrays.stream(arr).max().getAsInt();
while (low <= high) {
int mid = (low + high) / 2 ;
int chocolate = cal(arr, mid);
if (chocolate == K)
return mid;
else if (chocolate < K)
high = mid - 1 ;
else {
low = mid + 1 ;
if (mid > high)
high = mid;
}
}
return high;
}
public static void main(String[] args)
{
int K = 7 ;
int arr[] = { 15 , 20 , 8 , 17 };
System.out.println(maximumCut(arr, K));
}
}
|
Python3
def cal(arr, mid):
chocolate = 0
for i in arr:
if i > = mid:
chocolate + = i - mid
return chocolate
def maximumCut(arr, K):
low = 0
high = max (arr)
while low < = high:
mid = (low + high) / / 2
chocolate = cal(arr, mid)
if chocolate = = K:
return mid
elif chocolate < K:
high = mid - 1
else :
low = mid + 1
if mid > high:
high = mid
return high
N, K = 4 , 7
arr = [ 15 , 20 , 8 , 17 ]
print (maximumCut(arr, K))
|
C#
using System;
using System.Collections.Generic;
using System.Linq;
class GFG {
static int cal(List< int > arr, int mid)
{
int chocolate = 0;
foreach ( int i in arr)
{
if (i >= mid)
chocolate += i - mid;
}
return chocolate;
}
static int maximumCut(List< int > arr, int K)
{
int low = 0;
int high = arr.Max();
while (low <= high) {
int mid = (low + high) / 2;
int chocolate = cal(arr, mid);
if (chocolate == K)
return mid;
else if (chocolate < K)
high = mid - 1;
else {
low = mid + 1;
if (mid > high)
high = mid;
}
}
return high;
}
public static void Main()
{
int K = 7;
List< int > arr = new List< int >() { 15, 20, 8, 17 };
Console.Write(maximumCut(arr, K));
}
}
|
Javascript
<script>
function cal(arr, mid) {
let chocolate = 0
for (let i = 0; i < arr.length; i++) {
if (arr[i] >= mid)
chocolate += arr[i] - mid
}
return chocolate
}
function maximumCut(arr, K) {
let low = 0
let high = arr[0];
for (let i = 1; i < arr.length; i++) {
high = Math.max(high, arr[i]);
}
while (low <= high) {
mid = Math.floor((low + high) / 2);
chocolate = cal(arr, mid)
if (chocolate == K) {
return mid
}
else if (chocolate < K) {
high = mid - 1
}
else {
low = mid + 1
if (mid > high)
high = mid
}
}
return high
}
let N = 4;
let K = 7;
let arr = [15, 20, 8, 17];
document.write(maximumCut(arr, K))
</script>
|
Time Complexity: O(N*log N)
Auxiliary Space: O(1)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!