# Distributing Blueberry Cheese Cake among Students

Last Updated : 13 Dec, 2023

There is a school in a village. It has N classes. One fine day, someone donated B blueberry cheesecakes to schools. Now you need to divide these cakes such that:

• Each class gets at least 1 cake.
• Each class will share the cake(s) among students.
• Your aim is to minimize the maximum number of students per cake in any class.

Examples:

Input: N = 1, B = 2, ClassList = 35
Output: 18
Explanation: The number of students in each cake will be 17 and 18, and the maximum of them is 18.

Input: N = 2, B = 7, ClassList = 20 50
Output: 10
Explanation: The number of cakes will be 2 for the first and 5 for the second class, so there will be a maximum of 10 students for each cake.

Basic Approach: The basic way to solve the problem is as follows:

• First, we will check whether is it possible to distribute at least 1 cake per class, distributing will not be possible only when the number of cakes is less than the number of classes, returning -1 in this scenario.
• After that we will distribute 1 cake per class, then we will find the class that has a maximum number of students per cake and give them an extra cake to minimize it, again repeat the same process until we have no cakes left.
• At the end, we will return the maximum number of students per cake among all classes.

Below is the implementation of the above idea.

## C++

 `// C++ code for the above approach:` `#include ` `using` `namespace` `std;`   `int` `distribution(``int` `n, ``int` `b, vector<``float``>& ClassList)` `{` `    ``// Check if distributing cakes is possible` `    ``if` `(n > b) {` `        ``return` `-1;` `    ``}`   `    ``// CakeList will store the number of students` `    ``// per cake of each class` `    ``vector<``float``> CakeList = ClassList;`   `    ``// Initialize the number of cakes per class to 1` `    ``vector<``float``> CakePerClass(n, 1);`   `    ``// Adjust available cakes for initial distribution` `    ``b = b - n;`   `    ``// Distribute remaining cakes among classes` `    ``while` `(b > 0) {` `        ``// Decrease the number of remaining cakes` `        ``b--;`   `        ``// Find the class with the maximum number of` `        ``// students per cake of each class` `        ``int` `ind` `            ``= max_element(CakeList.begin(), CakeList.end())` `            ``- CakeList.begin();`   `        ``// Distribute a cake to the selected class` `        ``CakeList[ind]` `            ``= ClassList[ind] / (CakePerClass[ind] + 1);`   `        ``// Increment the number of cakes for the class` `        ``CakePerClass[ind]++;` `    ``}`   `    ``// Return the maximum number of students per cake` `    ``// after distributing all the cakes` `    ``return` `ceil``(` `        ``*max_element(CakeList.begin(), CakeList.end()));` `}`   `int` `main()` `{` `    ``int` `N = 1; ``// number of classes` `    ``int` `B = 2; ``// number of blueberry cakes` `    ``vector<``float``> ClassList` `        ``= { 35 }; ``// number of students in each class`   `    ``// Call the distribution function and print the result` `    ``cout << distribution(N, B, ClassList) << endl;`   `    ``return` `0;` `}`   `// This code is contributed by the Author`

## Java

 `import` `java.util.ArrayList;` `import` `java.util.Collections;` `import` `java.util.List;`   `public` `class` `CakeDistribution {`   `    ``public` `static` `int` `distribution(``int` `n, ``int` `b, List classList) {` `        ``// Check if distributing cakes is possible` `        ``if` `(n > b) {` `            ``return` `-``1``;` `        ``}`   `        ``// CakeList will store the number of students` `        ``// per cake of each class` `        ``List cakeList = ``new` `ArrayList<>(classList);`   `        ``// Initialize the number of cakes per class to 1` `        ``List cakePerClass = ``new` `ArrayList<>(Collections.nCopies(n, ``1``.0f));`   `        ``// Adjust available cakes for initial distribution` `        ``b = b - n;`   `        ``// Distribute remaining cakes among classes` `        ``while` `(b > ``0``) {` `            ``// Decrease the number of remaining cakes` `            ``b--;`   `            ``// Find the class with the maximum number of` `            ``// students per cake of each class` `            ``int` `ind = cakeList.indexOf(Collections.max(cakeList));`   `            ``// Distribute a cake to the selected class` `            ``cakeList.set(ind, classList.get(ind) / (cakePerClass.get(ind) + ``1``));`   `            ``// Increment the number of cakes for the class` `            ``cakePerClass.set(ind, cakePerClass.get(ind) + ``1``);` `        ``}`   `        ``// Return the maximum number of students per cake` `        ``// after distributing all the cakes` `        ``return` `(``int``) Math.ceil(Collections.max(cakeList));` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``int` `N = ``1``; ``// number of classes` `        ``int` `B = ``2``; ``// number of blueberry cakes` `        ``List classList = ``new` `ArrayList<>();` `        ``classList.add(``35``.0f); ``// number of students in each class`   `        ``// Call the distribution function and print the result` `        ``System.out.println(distribution(N, B, classList));` `    ``}` `}`   `// This code is contributed by shivamgupta0987654321`

## Python3

 `# Python3 implementation of above approach` `import` `math`     `def` `distribution(n, b, ClassList):`   `    ``# Check if distributing cakes is possible` `    ``if` `n > b:` `        ``return` `-``1`   `    ``# ClassList will store number of students` `    ``# per cake of each class` `    ``CakeList ``=` `ClassList.copy()`   `    ``# Initialize the number of cakes per class to 1` `    ``CakePerClass ``=` `[``1` `for` `i ``in` `range``(n)]`   `    ``# Adjust available cakes for initial distribution` `    ``b ``=` `b ``-` `n`   `    ``# Distribute remaining cakes among classes` `    ``while` `b:` `        ``# Decrease the number of remaining cakes` `        ``b ``-``=` `1`   `        ``# Find the class with maximum number of` `        ``# students per cake of each class` `        ``ind ``=` `CakeList.index(``max``(CakeList))`   `        ``# Distribute a cake to the selected class` `        ``CakeList[ind] ``=` `ClassList[ind] ``/` `(CakePerClass[ind] ``+` `1``)`   `        ``# Increment the number of cakes for the class` `        ``CakePerClass[ind] ``+``=` `1`   `    ``# Return the maximum number of students per cake` `    ``# after distributing all the cakes` `    ``return` `math.ceil(``max``(CakeList))`     `# Driver Code` `N ``=` `1`  `# number of classes` `B ``=` `2`  `# number of blueberry cakes` `ClassList ``=` `[``35``]  ``# number of students in each class`   `# Call the distribution function and print the result` `print``(distribution(N, B, ClassList))`   `# This code is contributed by the Author`

## C#

 `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `public` `class` `GFG` `{` `    ``public` `static` `int` `Distribution(``int` `n, ``int` `b, List<``float``> classList)` `    ``{` `        ``// Check if distributing cakes is possible` `        ``if` `(n > b)` `        ``{` `            ``return` `-1;` `        ``}`   `        ``// CakeList will store the number of students` `        ``// per cake of each class` `        ``List<``float``> cakeList = ``new` `List<``float``>(classList);`   `        ``// Initialize the number of cakes per class to 1` `        ``List<``float``> cakePerClass = Enumerable.Repeat(1.0f, n).ToList();`   `        ``// Adjust available cakes for initial distribution` `        ``b = b - n;`   `        ``// Distribute remaining cakes among classes` `        ``while` `(b > 0)` `        ``{` `            ``// Decrease the number of remaining cakes` `            ``b--;`   `            ``// Find the class with the maximum number of` `            ``// students per cake of each class` `            ``int` `ind = cakeList.IndexOf(cakeList.Max());`   `            ``// Distribute a cake to the selected class` `            ``cakeList[ind] = classList[ind] / (cakePerClass[ind] + 1);`   `            ``// Increment the number of cakes for the class` `            ``cakePerClass[ind] += 1;` `        ``}`   `        ``// Return the maximum number of students per cake` `        ``// after distributing all the cakes` `        ``return` `(``int``)Math.Ceiling(cakeList.Max());` `    ``}`   `    ``public` `static` `void` `Main(``string``[] args)` `    ``{` `        ``int` `N = 1; ``// number of classes` `        ``int` `B = 2; ``// number of blueberry cakes` `        ``List<``float``> classList = ``new` `List<``float``>();` `        ``classList.Add(35.0f); ``// number of students in each class`   `        ``// Call the distribution function and print the result` `        ``Console.WriteLine(Distribution(N, B, classList));` `    ``}` `}` `// This code is contributed by Rohit Singh`

## Javascript

 `// JavaScript code for the above approach:` `function` `distribution(n, b, classList) {` `    ``// Check if distributing cakes is possible` `    ``if` `(n > b) {` `        ``return` `-1;` `    ``}`   `    ``// CakeList will store the number of students` `    ``// per cake of each class` `    ``let cakeList = [...classList];`   `    ``// Initialize the number of cakes per class to 1` `    ``let cakePerClass = ``new` `Array(n).fill(1);`   `    ``// Adjust available cakes for initial distribution` `    ``b = b - n;`   `    ``// Distribute remaining cakes among classes` `    ``while` `(b > 0) {` `        ``// Decrease the number of remaining cakes` `        ``b--;`   `        ``// Find the class with the maximum number of` `        ``// students per cake of each class` `        ``let ind = cakeList.indexOf(Math.max(...cakeList));`   `        ``// Distribute a cake to the selected class` `        ``cakeList[ind] = classList[ind] / (cakePerClass[ind] + 1);`   `        ``// Increment the number of cakes for the class` `        ``cakePerClass[ind]++;` `    ``}`   `    ``// Return the maximum number of students per cake` `    ``// after distributing all the cakes` `    ``return` `Math.ceil(Math.max(...cakeList));` `}`   `// Driver Code`   `const N = 1; ``// number of classes` `const B = 2; ``// number of blueberry cakes` `const ClassList = [35]; ``// number of students in each class`   `// Call the distribution function and print the result` `console.log(distribution(N, B, ClassList));`

Output

```18

```

Time Complexity: O(N * B),

Auxiliary Space: O(N), where N is number of classes and B is number of blueberry cakes.

Efficient Approach: To solve the problem using Binary Search follow the below idea:

Instead of distributing cakes one by one, we can set a value for the “maximum students per cake” and then check if it’s possible to distribute the cakes in a way that meets this value. If we can achieve this distribution, we’ll increase the “maximum students per cake” and try again. Conversely, if we can’t achieve the desired distribution, we’ll decrease the “maximum students per cake” and attempt to find a feasible distribution.

• To do this we can use Binary Search by setting lower bound l to 1 as in the best case scenario we are able to distribute 1 cake per child, and upper bound r to maximum student count among classes as in the worst case scenario we will have to distribute 1 cake per class.
• Now In each iteration we will find a mid and then calculate the total number of cakes required and change the upper or lower bound accordingly.
• To calculate the total number of cakes required for the current mid value, iterate through each ClassList and determine how many cakes are needed to accommodate the students in that class while ensuring that each cake can have at most mid students. Sum up these calculations to obtain the total cakes required.

Below is the implementation of the above idea.

## C++

 `// C++ code for the above approach:` `#include ` `using` `namespace` `std;`   `int` `EfficientDistribution(``int` `n, ``int` `b,` `                        ``vector<``int``>& ClassList)` `{` `    ``// Initialize the lower bound as 1` `    ``int` `l = 1;`   `    ``// Set the upper bound as the maximum student count` `    ``// among classes` `    ``int` `r` `        ``= *max_element(ClassList.begin(), ClassList.end());`   `    ``// Check if distributing cakes is not feasible due to` `    ``// inadequate cakes` `    ``if` `(b < n) {` `        ``return` `-1;` `    ``}`   `    ``// Perform binary search to find the maximum students` `    ``// per cake` `    ``while` `(l < r) {` `        ``// Calculate the middle value of the current search` `        ``// range` `        ``int` `mid = (l + r) / 2;`   `        ``// Initialize the total number of cakes required` `        ``int` `cakes_req = 0;`   `        ``// Calculate the total required cakes for current` `        ``// students per cake value` `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``cakes_req += ``ceil``((``float``)ClassList[i] / mid);` `        ``}`   `        ``// Check if the current distribution is feasible` `        ``// within the given cake limit` `        ``if` `(cakes_req <= b) {` `            ``r = mid; ``// Update the upper bound` `        ``}` `        ``else` `{` `            ``l = mid + 1; ``// Update the lower bound` `        ``}` `    ``}`   `    ``return` `r; ``// Return the maximum students per cake` `}`   `// Drivers code` `int` `main()` `{` `    ``int` `N = 1; ``// Number of classes` `    ``int` `B = 2; ``// Number of blueberry cakes` `    ``vector<``int``> ClassList` `        ``= { 35 }; ``// Number of students in each class`   `    ``// Call the EfficientDistribution function and print the` `    ``// result` `    ``cout << EfficientDistribution(N, B, ClassList) << endl;`   `    ``return` `0;` `}`   `// This code is contributed by the Author`

## Java

 `import` `java.util.ArrayList;` `import` `java.util.Collections;`   `public` `class` `GFG {`   `    ``static` `int` `efficientDistribution(``int` `n, ``int` `b, ArrayList classList) {` `        ``// Initialize the lower bound as 1` `        ``int` `l = ``1``;`   `        ``// Set the upper bound as the maximum student count` `        ``// among classes` `        ``int` `r = Collections.max(classList);`   `        ``// Check if distributing cakes is not feasible due to` `        ``// inadequate cakes` `        ``if` `(b < n) {` `            ``return` `-``1``;` `        ``}`   `        ``// Perform binary search to find the maximum students` `        ``// per cake` `        ``while` `(l < r) {` `            ``// Calculate the middle value of the current search` `            ``// range` `            ``int` `mid = (l + r) / ``2``;`   `            ``// Initialize the total number of cakes required` `            ``int` `cakesReq = ``0``;`   `            ``// Calculate the total required cakes for current` `            ``// students per cake value` `            ``for` `(``int` `i = ``0``; i < n; i++) {` `                ``cakesReq += Math.ceil((``double``) classList.get(i) / mid);` `            ``}`   `            ``// Check if the current distribution is feasible` `            ``// within the given cake limit` `            ``if` `(cakesReq <= b) {` `                ``r = mid; ``// Update the upper bound` `            ``} ``else` `{` `                ``l = mid + ``1``; ``// Update the lower bound` `            ``}` `        ``}`   `        ``return` `r; ``// Return the maximum students per cake` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``int` `N = ``1``; ``// Number of classes` `        ``int` `B = ``2``; ``// Number of blueberry cakes` `        ``ArrayList classList = ``new` `ArrayList<>();` `        ``classList.add(``35``); ``// Number of students in each class`   `        ``// Call the efficientDistribution function and print the result` `        ``System.out.println(efficientDistribution(N, B, classList));` `    ``}` `}` `// This code is contributed by rohit singh`

## Python3

 `# Python3 implementation of above approach` `import` `math`     `def` `EfficientDistribution(n, b, ClassList):`   `    ``# Initialize the lower bound as 1` `    ``l ``=` `1`   `    ``# Set the upper bound as the maximum student count among classes` `    ``r ``=` `max``(ClassList)`   `    ``# Check if distributing cakes is not feasible due to inadequate cakes` `    ``if` `b < n:` `        ``return` `"-1"`   `    ``# Perform binary search to find the maximum students per cake` `    ``while` `l < r:` `        ``# Calculate the middle value of the current search range` `        ``mid ``=` `(l ``+` `r) ``/``/` `2`   `        ``# Initialize the total number of cakes required` `        ``cakes_req ``=` `0`   `        ``# Calculate the total required cakes for current students per cake value` `        ``for` `i ``in` `range``(n):` `            ``cakes_req ``+``=` `math.ceil(ClassList[i] ``/` `mid)`   `        ``# Check if the current distribution is feasible within the given cake limit` `        ``if` `cakes_req <``=` `b:` `            ``r ``=` `mid ``# Update the upper bound` `        ``else``:` `            ``l ``=` `mid ``+` `1` `# Update the lower bound`   `    ``return` `r ``# Return the maximum students per cake`     `# Driver Code` `N ``=` `1` `# Number of classes` `B ``=` `2` `# Number of blueberry cakes` `ClassList ``=` `[``35``] ``# Number of students in each class`   `# Call the EfficientDistribution function and print the result` `print``(EfficientDistribution(N, B, ClassList))`   `# This code is contributed by the Author`

## C#

 `using` `System;` `using` `System.Collections.Generic;` `using` `System.Linq;`   `class` `Program` `{` `    ``static` `int` `EfficientDistribution(``int` `n, ``int` `b, List<``int``> classList)` `    ``{` `        ``// Initialize the lower bound as 1` `        ``int` `l = 1;`   `        ``// Set the upper bound as the maximum student count` `        ``// among classes` `        ``int` `r = classList.Max();`   `        ``// Check if distributing cakes is not feasible due to` `        ``// inadequate cakes` `        ``if` `(b < n)` `        ``{` `            ``return` `-1;` `        ``}`   `        ``// Perform binary search to find the maximum students` `        ``// per cake` `        ``while` `(l < r)` `        ``{` `            ``// Calculate the middle value of the current search` `            ``// range` `            ``int` `mid = (l + r) / 2;`   `            ``// Initialize the total number of cakes required` `            ``int` `cakesReq = 0;`   `            ``// Calculate the total required cakes for current` `            ``// students per cake value` `            ``foreach` `(``int` `students ``in` `classList)` `            ``{` `                ``cakesReq += (``int``)Math.Ceiling((``double``)students / mid);` `            ``}`   `            ``// Check if the current distribution is feasible` `            ``// within the given cake limit` `            ``if` `(cakesReq <= b)` `            ``{` `                ``r = mid; ``// Update the upper bound` `            ``}` `            ``else` `            ``{` `                ``l = mid + 1; ``// Update the lower bound` `            ``}` `        ``}`   `        ``return` `r; ``// Return the maximum students per cake` `    ``}`   `    ``static` `void` `Main()` `    ``{` `        ``int` `N = 1; ``// Number of classes` `        ``int` `B = 2; ``// Number of blueberry cakes` `        ``List<``int``> classList = ``new` `List<``int``> { 35 }; ``// Number of students in each class`   `        ``// Call the EfficientDistribution method and print the result` `        ``Console.WriteLine(EfficientDistribution(N, B, classList));` `    ``}` `}`

## Javascript

 `// Javascript code for the above approach:`   `function` `EfficientDistribution(n, b, ClassList) {` `    ``// Initialize the lower bound as 1` `    ``let l = 1;`   `    ``// Set the upper bound as the maximum student count` `    ``// among classes` `    ``let r = ClassList.reduce((a, b) => Math.max(a, b), -Infinity);`   `    ``// Check if distributing cakes is not feasible due to` `    ``// inadequate cakes` `    ``if` `(b < n) {` `        ``return` `-1;` `    ``}`   `    ``// Perform binary search to find the maximum students` `    ``// per cake` `    ``while` `(l < r) {` `        ``// Calculate the middle value of the current search` `        ``// range` `        ``let mid = Math.trunc((l + r) / 2);`   `        ``// Initialize the total number of cakes required` `        ``let cakes_req = 0;`   `        ``// Calculate the total required cakes for current` `        ``// students per cake value` `        ``for` `(let i = 0; i < n; i++) {` `            ``cakes_req += Math.ceil(ClassList[i] / mid);` `        ``}`   `        ``// Check if the current distribution is feasible` `        ``// within the given cake limit` `        ``if` `(cakes_req <= b) {` `            ``r = mid; ``// Update the upper bound` `        ``} ``else` `{` `            ``l = mid + 1; ``// Update the lower bound` `        ``}` `    ``}`   `    ``return` `r; ``// Return the maximum students per cake` `}`   `// Drivers code` `let N = 1; ``// Number of classes` `let B = 2; ``// Number of blueberry cakes` `let ClassList = [35]; ``// Number of students in each class`   `// Call the EfficientDistribution function and print the` `// result` `console.log(EfficientDistribution(N, B, ClassList));`   `// This code is contributed by the ragul21`

Output

```18

```

Time Complexity: O(N * log R),

Auxiliary Space: O(N), where N is number of classes and R is maximum student count among classes.