Given N candies, M people, and an array arr[] of M positive integers, the task is to find the minimum value of K such that a Person A is able to consume the total of at least ceil of (N/(M + 1)) candies according to the following rules:
- In the first turn, Person A consumes a minimum of the number of candies left and K.
- In the next M turns, each ith Person over then range [0, M-1] consumes floor of arr[i] percentage of the remaining candies.
- Repeat the above steps, until no candies are left.
Examples:
Input: N = 13, M = 1, arr[] = {50}
Output: 3
Explanation:
For the value K as 3, the good share is the ceil of (13/2) = 7. Following are the turns that takes place:
- Person A takes min(3,13)=3 candies. Therefore, the candies left = 13 – 3 = 10.
- Person 0 takes arr[0](= 50)% of the 10 left candies, i.e., 5 candies. Therefore, the candies left = 10 – 5 = 5.
- Person A takes min(3,5)=3 candies. Therefore, the candies left = 5 – 3 = 2.
- Person 0 takes arr[0](= 50)% of the 2 left candies, i.e., 1 candies. Therefore, the candies left = 2 – 1 = 1.
- Person A takes 1 candy. Therefore, the candies left = 1 – 1 = 0.
After the above turns, the candies taken by the person is 3 + 3 + 1 = 7, which is at least (N/(M + 1)) candies, i.e., 13/2 = 6.
Input: N = 13, M = 2, arr[] = {40, 50}
Output: 2
Naive Approach: The simplest approach to solve the given problem is to check for each amount of candies Person A will get for all the possible values of K. Follow the below steps to solve this problem:
- Find the value of (N/(M + 1)) and stores it in a variable, say good as this is the minimum amount of candies Person A wants to take.
-
Iterate over all the values of K in the range [1, N] and perform the following steps:
- For each value of K, simulate the process mentioned above and count the total number of candies Person A will get.
- If the amount of candies is at least the value of good, then break out of the loop. Otherwise, continue the iteration.
- After completing the above steps, print the current value of K as the result.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to find minimum value of // K such that the first person gets // at least (N/(M+1)) candies void minimumK(vector< int > &arr, int M,
int N)
{ // Find the minimum required value
// of candies for the first person
int good = ceil ((N * 1.0)
/ ((M + 1) * 1.0));
// Iterate K from [1, n]
for ( int i = 1; i <= N; i++) {
int K = i;
// Total number of candies
int candies = N;
// Candies taken by Person 1
int taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += min(K, candies);
candies -= min(K, candies);
// Traverse the array arr[]
for ( int j = 0; j < M; j++) {
// Amount consumed by the
// person j
int consume = (arr[j]
* candies) / 100;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good) {
cout << i;
return ;
}
}
} // Driver Code int main()
{ int N = 13, M = 1;
vector< int > arr = { 50 };
minimumK(arr, M, N);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG{
// Function to find minimum value of // K such that the first person gets // at least (N/(M+1)) candies static void minimumK(ArrayList<Integer> arr, int M,
int N)
{ // Find the minimum required value
// of candies for the first person
int good = ( int )((N * 1.0 ) / ((M + 1 ) * 1.0 )) + 1 ;
// Iterate K from [1, n]
for ( int i = 1 ; i <= N; i++)
{
int K = i;
// Total number of candies
int candies = N;
// Candies taken by Person 1
int taken = 0 ;
while (candies > 0 )
{
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the array arr[]
for ( int j = 0 ; j < M; j++)
{
// Amount consumed by the
// person j
int consume = (arr.get(j) * candies) / 100 ;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good)
{
System.out.print(i);
return ;
}
}
} // Driver Code public static void main(String[] args)
{ int N = 13 , M = 1 ;
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add( 50 );
minimumK(arr, M, N);
} } // This code is contributed by subhammahato348 |
# Python 3 program for the above approach import math
# Function to find minimum value of # K such that the first person gets # at least (N/(M+1)) candies def minimumK(arr, M, N):
# Find the minimum required value
# of candies for the first person
good = math.ceil((N * 1.0 ) / ((M + 1 ) * 1.0 ))
# Iterate K from [1, n]
for i in range ( 1 , N + 1 ):
K = i
# Total number of candies
candies = N
# Candies taken by Person 1
taken = 0
while (candies > 0 ):
# Candies taken by 1st
# person is minimum of K
# and candies left
taken + = min (K, candies)
candies - = min (K, candies)
# Traverse the array arr[]
for j in range (M):
# Amount consumed by the
# person j
consume = (arr[j]
* candies) / 100
# Update the number
# of candies
candies - = consume
# Good share of candies achieved
if (taken > = good):
print (i)
return
# Driver Code if __name__ = = "__main__" :
N = 13
M = 1
arr = [ 50 ]
minimumK(arr, M, N)
# This code is contributed by ukasp.
|
// C# program for the above approach using System;
using System.Collections.Generic;
class GFG{
// Function to find minimum value of // K such that the first person gets // at least (N/(M+1)) candies static void minimumK(List< int > arr, int M,
int N)
{ // Find the minimum required value
// of candies for the first person
int good = ( int )((N * 1.0) / ((M + 1) * 1.0))+1;
// Iterate K from [1, n]
for ( int i = 1; i <= N; i++) {
int K = i;
// Total number of candies
int candies = N;
// Candies taken by Person 1
int taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.Min(K, candies);
candies -= Math.Min(K, candies);
// Traverse the array arr[]
for ( int j = 0; j < M; j++) {
// Amount consumed by the
// person j
int consume = (arr[j]
* candies) / 100;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good) {
Console.Write(i);
return ;
}
}
} // Driver Code public static void Main()
{ int N = 13, M = 1;
List< int > arr = new List< int >();
arr.Add(50);
minimumK(arr, M, N);
} } // This code is contributed by SURENDRA_GANGWAR. |
<script> // JavaScript program for the above approach // Function to find minimum value of // K such that the first person gets // at least (N/(M+1)) candies function minimumK(arr, M, N)
{ // Find the minimum required value
// of candies for the first person
let good = Math.floor((N * 1.0) / ((M + 1) * 1.0))+1;
// Iterate K from [1, n]
for (let i = 1; i <= N; i++) {
let K = i;
// Total number of candies
let candies = N;
// Candies taken by Person 1
let taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the array arr[]
for (let j = 0; j < M; j++) {
// Amount consumed by the
// person j
let consume = (arr[j]
* candies) / 100;
// Update the number
// of candies
candies -= consume;
}
}
// Good share of candies achieved
if (taken >= good) {
document.write(i);
return ;
}
}
} // Driver Code let N = 13, M = 1;
let arr = new Array();
arr.push(50);
minimumK(arr, M, N);
// This code is contributed by _Saurabh_Jaiswal </script> |
Output:
3
Time Complexity: O(N2)
Auxiliary Space: O(1)
Efficient Approach: The above approach can also be optimized by using Binary Search. Follow the steps below to solve the problem:
- Find the value of (N/(M + 1)) and stores it in a variable, say good as this is the minimum amount of candies Person A wants to take.
- Initialize two variables, say low and high as 1 and N respectively.
- Iterate until low is less than high and perform the following steps:
- Find the value of mid as (low + high)/2.
- Find the minimum number of candies taken by Person A for the value of K as mid by simulating the process mentioned above.
- If the number of candies taken by Person A is at least good then update the value of high as mid. Otherwise, update the value of low as (mid + 1).
- After completing the above steps, print the value of high as the resultant minimum value of K.
Below is the implementation of the above approach:
// C++ program for the above approach #include <bits/stdc++.h> using namespace std;
// Function to check if the value of // mid gives at least (N/(M + 1)) // candies or not bool check( int K, int n, int m,
vector< int > arr,
int good_share)
{ int candies = n, taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += min(K, candies);
candies -= min(K, candies);
// Traverse the given array
for ( int j = 0; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr[j] * candies) / 100;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
} // Function to find minimum value of // K such that the first person gets // at least (N/(M+1)) candies void minimumK(vector< int > &arr, int N,
int M)
{ // Find the minimum required value
// of candies for the first person
int good_share = ceil ((N * 1.0)
/ ((M + 1) * 1.0));
int lo = 1, hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr,
good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1;
}
}
// Print the resultant minimum
// value of K
cout << hi;
} // Driver Code int main()
{ int N = 13, M = 1;
vector< int > arr = { 50 };
minimumK(arr, N, M);
return 0;
} |
// Java program for the above approach import java.util.*;
class GFG {
// Function to check if the value of // mid gives at least (N/(M + 1)) // candies or not static boolean check( int K, int n, int m,
ArrayList<Integer> arr,
int good_share)
{ int candies = n, taken = 0 ;
while (candies > 0 ) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the given array
for ( int j = 0 ; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr.get(j) * candies) / 100 ;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
} // Function to find minimum value of // K such that the first person gets // at least (N/(M+1)) candies static void minimumK(ArrayList<Integer> arr, int N,
int M)
{ // Find the minimum required value
// of candies for the first person
int good_share = ( int )Math.ceil((N * 1.0 )
/ ((M + 1 ) * 1.0 ));
int lo = 1 , hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2 ;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr,
good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1 ;
}
}
// Print the resultant minimum
// value of K
System.out.print(hi);
} // Driver Code public static void main(String[] args)
{ int N = 13 , M = 1 ;
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add( 50 );
minimumK(arr, N, M);
} } // This code is contributed by avijitmondal1998. |
import math
class GFG :
# Function to check if the value of
# mid gives at least (N/(M + 1))
# candies or not
@staticmethod
def check( K, n, m, arr, good_share) :
candies = n
taken = 0
while (candies > 0 ) :
# Candies taken by 1st
# person is minimum of K
# and candies left
taken + = min (K,candies)
candies - = min (K,candies)
# Traverse the given array
j = 0
while (j < m) :
# Amount consumed by
# person j
consume = int ((arr[j] * candies) / 100 )
# Update the count of
# candies
candies - = consume
j + = 1
# Check if person 1 gets the
# good share of candies
return (taken > = good_share)
# Function to find minimum value of
# K such that the first person gets
# at least (N/(M+1)) candies
@staticmethod
def minimumK( arr, N, M) :
# Find the minimum required value
# of candies for the first person
good_share = int (math.ceil((N * 1.0 ) / ((M + 1 ) * 1.0 )))
lo = 1
hi = N
# Iterate until low is less
# than or equal to mid
while (lo < hi) :
# Find the value of mid
mid = int ((lo + hi) / 2 )
# Check for mid, whether it
# can be the possible value
# of K or not
if (GFG.check(mid, N, M, arr, good_share)) :
# Update the value of hi
hi = mid
else :
lo = mid + 1
# Print the resultant minimum
# value of K
print (hi, end = "")
# Driver Code
@staticmethod
def main( args) :
N = 13
M = 1
arr = []
arr.append( 50 )
GFG.minimumK(arr, N, M)
if __name__ = = "__main__" :
GFG.main([])
|
// C# code to implement the approach using System;
using System.Collections.Generic;
class GFG {
// Function to check if the value of
// mid gives at least (N/(M + 1))
// candies or not
static bool check( int K, int n, int m, List< int > arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
// Candies taken by 1st
// person is minimum of K
// and candies left
taken += Math.Min(K, candies);
candies -= Math.Min(K, candies);
// Traverse the given array
for ( int j = 0; j < m; j++) {
// Amount consumed by
// person j
int consume = (arr[j] * candies) / 100;
// Update the count of
// candies
candies -= consume;
}
}
// Check if person 1 gets the
// good share of candies
return (taken >= good_share);
}
// Function to find minimum value of
// K such that the first person gets
// at least (N/(M+1)) candies
static void minimumK(List< int > arr, int N, int M)
{
// Find the minimum required value
// of candies for the first person
int good_share = ( int )Math.Ceiling(
(N * 1.0) / ((M + 1) * 1.0));
int lo = 1, hi = N;
// Iterate until low is less
// than or equal to mid
while (lo < hi) {
// Find the value of mid
int mid = (lo + hi) / 2;
// Check for mid, whether it
// can be the possible value
// of K or not
if (check(mid, N, M, arr, good_share)) {
// Update the value of hi
hi = mid;
}
// Otherwise, update the
// value of lo
else {
lo = mid + 1;
}
}
// Print the resultant minimum
// value of K
Console.WriteLine(hi);
}
// Driver Code
public static void Main( string [] args)
{
int N = 13, M = 1;
List< int > arr = new List< int >();
arr.Add(50);
minimumK(arr, N, M);
}
} // This code is contributed by phasing17 |
// Class in javascript class GFG { // Static method in javascript
static check(K, n, m, arr, good_share) {
let candies = n;
let taken = 0;
while (candies > 0)
{
// Candies taken by 1st person is minimum of K and candies left
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
// Traverse the given array
let j = 0;
while (j < m)
{
// Amount consumed by person j
let consume = parseInt(((arr[j] * candies) / 100).toFixed(0));
// Update the count of candies
candies -= consume;
j += 1;
}
}
// Check if person 1 gets the good share of candies
return taken >= good_share;
}
// Function to find minimum value of K such that the first person gets at least (N/(M+1)) candies
static minimumK(arr, N, M)
{
// Find the minimum required value of candies for the first person
let good_share = Math.ceil((N * 1.0) / ((M + 1) * 1.0));
let lo = 1;
let hi = N;
// Iterate until low is less than or equal to mid
while (lo < hi)
{
// Find the value of mid
let mid = parseInt((lo + hi) / 2);
// Check for mid, whether it can be the possible value of K or not
if (GFG.check(mid, N, M, arr, good_share))
{
// Update the value of hi
hi = mid;
} else {
lo = mid + 1;
}
}
// Print the resultant minimum value of K
console.log(hi);
}
// Driver code in javascript
static main(args) {
let N = 13;
let M = 1;
let arr = [];
arr.push(50);
GFG.minimumK(arr, N, M);
}
} // Main function ( function () {
GFG.main([]);
})(); // This code is contributed by phasing17. |
3
Time Complexity: O(N * log N)
Auxiliary Space: O(1)