Minimize K to let Person A consume at least ceil(N/(M + 1)) candies based on given rules
Last Updated :
10 Feb, 2023
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++
#include <bits/stdc++.h>
using namespace std;
void minimumK(vector< int > &arr, int M,
int N)
{
int good = ceil ((N * 1.0)
/ ((M + 1) * 1.0));
for ( int i = 1; i <= N; i++) {
int K = i;
int candies = N;
int taken = 0;
while (candies > 0) {
taken += min(K, candies);
candies -= min(K, candies);
for ( int j = 0; j < M; j++) {
int consume = (arr[j]
* candies) / 100;
candies -= consume;
}
}
if (taken >= good) {
cout << i;
return ;
}
}
}
int main()
{
int N = 13, M = 1;
vector< int > arr = { 50 };
minimumK(arr, M, N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static void minimumK(ArrayList<Integer> arr, int M,
int N)
{
int good = ( int )((N * 1.0 ) / ((M + 1 ) * 1.0 )) + 1 ;
for ( int i = 1 ; i <= N; i++)
{
int K = i;
int candies = N;
int taken = 0 ;
while (candies > 0 )
{
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
for ( int j = 0 ; j < M; j++)
{
int consume = (arr.get(j) * candies) / 100 ;
candies -= consume;
}
}
if (taken >= good)
{
System.out.print(i);
return ;
}
}
}
public static void main(String[] args)
{
int N = 13 , M = 1 ;
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add( 50 );
minimumK(arr, M, N);
}
}
|
Python3
import math
def minimumK(arr, M, N):
good = math.ceil((N * 1.0 ) / ((M + 1 ) * 1.0 ))
for i in range ( 1 , N + 1 ):
K = i
candies = N
taken = 0
while (candies > 0 ):
taken + = min (K, candies)
candies - = min (K, candies)
for j in range (M):
consume = (arr[j]
* candies) / 100
candies - = consume
if (taken > = good):
print (i)
return
if __name__ = = "__main__" :
N = 13
M = 1
arr = [ 50 ]
minimumK(arr, M, N)
|
C#
using System;
using System.Collections.Generic;
class GFG{
static void minimumK(List< int > arr, int M,
int N)
{
int good = ( int )((N * 1.0) / ((M + 1) * 1.0))+1;
for ( int i = 1; i <= N; i++) {
int K = i;
int candies = N;
int taken = 0;
while (candies > 0) {
taken += Math.Min(K, candies);
candies -= Math.Min(K, candies);
for ( int j = 0; j < M; j++) {
int consume = (arr[j]
* candies) / 100;
candies -= consume;
}
}
if (taken >= good) {
Console.Write(i);
return ;
}
}
}
public static void Main()
{
int N = 13, M = 1;
List< int > arr = new List< int >();
arr.Add(50);
minimumK(arr, M, N);
}
}
|
Javascript
<script>
function minimumK(arr, M, N)
{
let good = Math.floor((N * 1.0) / ((M + 1) * 1.0))+1;
for (let i = 1; i <= N; i++) {
let K = i;
let candies = N;
let taken = 0;
while (candies > 0) {
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
for (let j = 0; j < M; j++) {
let consume = (arr[j]
* candies) / 100;
candies -= consume;
}
}
if (taken >= good) {
document.write(i);
return ;
}
}
}
let N = 13, M = 1;
let arr = new Array();
arr.push(50);
minimumK(arr, M, N);
</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++
#include <bits/stdc++.h>
using namespace std;
bool check( int K, int n, int m,
vector< int > arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
taken += min(K, candies);
candies -= min(K, candies);
for ( int j = 0; j < m; j++) {
int consume = (arr[j] * candies) / 100;
candies -= consume;
}
}
return (taken >= good_share);
}
void minimumK(vector< int > &arr, int N,
int M)
{
int good_share = ceil ((N * 1.0)
/ ((M + 1) * 1.0));
int lo = 1, hi = N;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (check(mid, N, M, arr,
good_share)) {
hi = mid;
}
else {
lo = mid + 1;
}
}
cout << hi;
}
int main()
{
int N = 13, M = 1;
vector< int > arr = { 50 };
minimumK(arr, N, M);
return 0;
}
|
Java
import java.util.*;
class GFG {
static boolean check( int K, int n, int m,
ArrayList<Integer> arr,
int good_share)
{
int candies = n, taken = 0 ;
while (candies > 0 ) {
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
for ( int j = 0 ; j < m; j++) {
int consume = (arr.get(j) * candies) / 100 ;
candies -= consume;
}
}
return (taken >= good_share);
}
static void minimumK(ArrayList<Integer> arr, int N,
int M)
{
int good_share = ( int )Math.ceil((N * 1.0 )
/ ((M + 1 ) * 1.0 ));
int lo = 1 , hi = N;
while (lo < hi) {
int mid = (lo + hi) / 2 ;
if (check(mid, N, M, arr,
good_share)) {
hi = mid;
}
else {
lo = mid + 1 ;
}
}
System.out.print(hi);
}
public static void main(String[] args)
{
int N = 13 , M = 1 ;
ArrayList<Integer> arr = new ArrayList<Integer>();
arr.add( 50 );
minimumK(arr, N, M);
}
}
|
Python3
import math
class GFG :
@staticmethod
def check( K, n, m, arr, good_share) :
candies = n
taken = 0
while (candies > 0 ) :
taken + = min (K,candies)
candies - = min (K,candies)
j = 0
while (j < m) :
consume = int ((arr[j] * candies) / 100 )
candies - = consume
j + = 1
return (taken > = good_share)
@staticmethod
def minimumK( arr, N, M) :
good_share = int (math.ceil((N * 1.0 ) / ((M + 1 ) * 1.0 )))
lo = 1
hi = N
while (lo < hi) :
mid = int ((lo + hi) / 2 )
if (GFG.check(mid, N, M, arr, good_share)) :
hi = mid
else :
lo = mid + 1
print (hi, end = "")
@staticmethod
def main( args) :
N = 13
M = 1
arr = []
arr.append( 50 )
GFG.minimumK(arr, N, M)
if __name__ = = "__main__" :
GFG.main([])
|
C#
using System;
using System.Collections.Generic;
class GFG {
static bool check( int K, int n, int m, List< int > arr,
int good_share)
{
int candies = n, taken = 0;
while (candies > 0) {
taken += Math.Min(K, candies);
candies -= Math.Min(K, candies);
for ( int j = 0; j < m; j++) {
int consume = (arr[j] * candies) / 100;
candies -= consume;
}
}
return (taken >= good_share);
}
static void minimumK(List< int > arr, int N, int M)
{
int good_share = ( int )Math.Ceiling(
(N * 1.0) / ((M + 1) * 1.0));
int lo = 1, hi = N;
while (lo < hi) {
int mid = (lo + hi) / 2;
if (check(mid, N, M, arr, good_share)) {
hi = mid;
}
else {
lo = mid + 1;
}
}
Console.WriteLine(hi);
}
public static void Main( string [] args)
{
int N = 13, M = 1;
List< int > arr = new List< int >();
arr.Add(50);
minimumK(arr, N, M);
}
}
|
Javascript
class GFG
{
static check(K, n, m, arr, good_share) {
let candies = n;
let taken = 0;
while (candies > 0)
{
taken += Math.min(K, candies);
candies -= Math.min(K, candies);
let j = 0;
while (j < m)
{
let consume = parseInt(((arr[j] * candies) / 100).toFixed(0));
candies -= consume;
j += 1;
}
}
return taken >= good_share;
}
static minimumK(arr, N, M)
{
let good_share = Math.ceil((N * 1.0) / ((M + 1) * 1.0));
let lo = 1;
let hi = N;
while (lo < hi)
{
let mid = parseInt((lo + hi) / 2);
if (GFG.check(mid, N, M, arr, good_share))
{
hi = mid;
} else {
lo = mid + 1;
}
}
console.log(hi);
}
static main(args) {
let N = 13;
let M = 1;
let arr = [];
arr.push(50);
GFG.minimumK(arr, N, M);
}
}
( function () {
GFG.main([]);
})();
|
Time Complexity: O(N * log N)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...