Open In App
Related Articles

Minimize K to let Person A consume at least ceil(N/(M + 1)) candies based on given rules

Improve
Improve
Improve
Like Article
Like
Save Article
Save
Report issue
Report

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:

  1. Person A takes min(3,13)=3 candies. Therefore, the candies left = 13 – 3 = 10.
  2. Person 0 takes arr[0](= 50)% of the 10 left candies, i.e., 5 candies. Therefore, the candies left = 10 – 5 = 5.
  3. Person A takes min(3,5)=3 candies. Therefore, the candies left = 5 – 3 = 2.
  4. Person 0 takes arr[0](= 50)% of the 2 left candies, i.e., 1 candies. Therefore, the candies left = 2 – 1 = 1.
  5. 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++

// 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

// 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

                    

Python3

# 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#

// 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.

                    

Javascript

<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++

// 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

// 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.

                    

Python3

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#

// 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

                    

Javascript

// 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.

                    

Output
3

Time Complexity: O(N * log N)
Auxiliary Space: O(1)



Last Updated : 10 Feb, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads