Distribute N candies among K people - GeeksforGeeks

25 Nov, 2021
Given N candies and K people. In the first turn, the first person gets 1 candy, the second gets 2 candies, and so on till K people. In the next turn, the first person gets K+1 candies, the second person gets k+2 candies, and so on. If the number of candies is less than the required number of candies at every turn, then the person receives the remaining number of candies. The task is to find the total number of candies every person has at the end. Examples:  
Input: N = 7, K = 4 Output: 1 2 3 1 At the first turn, the fourth people has to be given 4 candies, but there is only 1 left, hence he takes one only. Input: N = 10, K = 3 Output: 5 2 3 At the second turn first one receives 4 and then we have no more candies left. 
 
A naive approach is to iterate for every turn and distribute candies accordingly till candies are finished. Time complexity: O(Number of distributions)A better approach is to perform every turn in O(1) by calculating sum of natural numbers till the last term of series which will be (turns*k) and subtracting the sum of natural numbers till the last term of previous series which is (turns-1)*k. Keep doing this till the sum is less than N, once it exceeds then distribute candies in the given way till possible. We call a turn completed if every person gets the desired number of candies he is to get in a turn. Below is the implementation of the above approach:  
C++
Java
Python3
C#
PHP
Javascript
// C++ code for better approach// to distribute candies#include <bits/stdc++.h>using namespace std; // Function to find out the number of// candies every person receivedvoid candies(int n, int k){     // Count number of complete turns    int count = 0;     // Get the last term    int ind = 1;     // Stores the number of candies    int arr[k];     memset(arr, 0, sizeof(arr));     while (n) {         // Last term of last and        // current series        int f1 = (ind - 1) * k;        int f2 = ind * k;         // Sum of current and last  series        int sum1 = (f1 * (f1 + 1)) / 2;        int sum2 = (f2 * (f2 + 1)) / 2;         // Sum of current series only        int res = sum2 - sum1;         // If sum of current is less than N        if (res <= n) {            count++;            n -= res;            ind++;        }        else // Individually distribute        {            int i = 0;             // First term            int term = ((ind - 1) * k) + 1;             // Distribute candies till there            while (n > 0) {                 // Candies available                if (term <= n) {                    arr[i++] = term;                    n -= term;                    term++;                }                else // Not available                {                    arr[i++] = n;                    n = 0;                }            }        }    }     // Count the total candies    for (int i = 0; i < k; i++)        arr[i] += (count * (i + 1))                + (k * (count * (count - 1)) / 2);     // Print the total candies    for (int i = 0; i < k; i++)        cout << arr[i] << " ";} // Driver Codeint main(){    int n = 10, k = 3;    candies(n, k);     return 0;}
// Java  code for better approach// to distribute candies class GFG {    // Function to find out the number of    // candies every person received    static void candies(int n, int k){        int[] arr = new int[k];        int j = 0;        while(n>0){                         for(int i =0;i<k;i++){                j++;                if(n<=0){                    break;                }                else{                    if(j<n){                        arr[i] = arr[i]+j;                    }                    else{                        arr[i] = arr[i]+n;                    }                    n = n-j;                }                             }        }        for(int i:arr){            System.out.print(i+" ");        }    }            // Driver Code      public static void main(String[] args)      {        int n = 10, k = 3;        candies(n, k);      }    }         // This code is contributed by ihritik
# Python3 code for better approach# to distribute candiesimport math as mt # Function to find out the number of# candies every person receiveddef candies(n, k):     # Count number of complete turns    count = 0     # Get the last term    ind = 1     # Stores the number of candies    arr = [0 for i in range(k)]     while n > 0:         # Last term of last and        # current series        f1 = (ind - 1) * k        f2 = ind * k         # Sum of current and last series        sum1 = (f1 * (f1 + 1)) // 2        sum2 = (f2 * (f2 + 1)) //2         # Sum of current series only        res = sum2 - sum1         # If sum of current is less than N        if (res <= n):            count += 1            n -= res            ind += 1        else: # Individually distribute            i = 0             # First term            term = ((ind - 1) * k) + 1             # Distribute candies till there            while (n > 0):                 # Candies available                if (term <= n):                    arr[i] = term                    i += 1                    n -= term                    term += 1                else:                    arr[i] = n                    i += 1                    n = 0     # Count the total candies    for i in range(k):        arr[i] += ((count * (i + 1)) +                   (k * (count * (count - 1)) // 2))     # Print the total candies    for i in range(k):        print(arr[i], end = " ") # Driver Coden, k = 10, 3candies(n, k) # This code is contributed by Mohit kumar
// C# code for better approach// to distribute candies using System;class GFG{    // Function to find out the number of    // candies every person received    static void candies(int n, int k)    {             // Count number of complete turns        int count = 0;             // Get the last term        int ind = 1;             // Stores the number of candies        int []arr=new int[k];             for(int i=0;i<k;i++)         arr[i]=0;             while (n>0) {                 // Last term of last and            // current series            int f1 = (ind - 1) * k;            int f2 = ind * k;                 // Sum of current and last series            int sum1 = (f1 * (f1 + 1)) / 2;            int sum2 = (f2 * (f2 + 1)) / 2;                 // Sum of current series only            int res = sum2 - sum1;                 // If sum of current is less than N            if (res <= n) {                count++;                n -= res;                ind++;            }            else // Individually distribute            {                int i = 0;                     // First term                int term = ((ind - 1) * k) + 1;                     // Distribute candies till there                while (n > 0) {                         // Candies available                    if (term <= n) {                        arr[i++] = term;                        n -= term;                        term++;                    }                    else // Not available                    {                        arr[i++] = n;                        n = 0;                    }                }            }        }             // Count the total candies        for (int i = 0; i < k; i++)            arr[i] += (count * (i + 1))                    + (k * (count * (count - 1)) / 2);             // Print the total candies        for (int i = 0; i < k; i++)            Console.Write( arr[i] + " ");    }         // Driver Code    public static void Main()    {        int n = 10, k = 3;        candies(n, k);                  }}  // This code is contributed by ihritik
<?php// PHP code for better approach// to distribute candies // Function to find out the number of// candies every person receivedfunction candies($n, $k){     // Count number of complete turns    $count = 0;     // Get the last term    $ind = 1;     // Stores the number of candies    $arr = array_fill(0, $k, 0) ;         while ($n)    {         // Last term of last and        // current series        $f1 = ($ind - 1) * $k;        $f2 = $ind * $k;         // Sum of current and last series        $sum1 = floor(($f1 * ($f1 + 1)) / 2);        $sum2 = floor(($f2 * ($f2 + 1)) / 2);         // Sum of current series only        $res = $sum2 - $sum1;         // If sum of current is less than N        if ($res <= $n)        {            $count++;            $n -= $res;            $ind++;        }        else // Individually distribute        {            $i = 0;             // First term            $term = (($ind - 1) * $k) + 1;             // Distribute candies till there            while ($n > 0)            {                 // Candies available                if ($term <= $n)                {                    $arr[$i++] = $term;                    $n -= $term;                    $term++;                }                else // Not available                {                    $arr[$i++] = $n;                    $n = 0;                }            }        }    }     // Count the total candies    for ($i = 0; $i < $k; $i++)        $arr[$i] += floor(($count * ($i + 1)) + ($k *                          ($count * ($count - 1)) / 2));     // Print the total candies    for ($i = 0; $i < $k; $i++)        echo $arr[$i], " ";} // Driver Code$n = 10;$k = 3;candies($n, $k); // This code is contributed by Ryuga?>
<script> // JavaScript  code for better approach// to distribute candies     // Function to find out the number of    // candies every person received    function candies(n , k) {         // Count number of complete turns        var count = 0;         // Get the last term        var ind = 1;         // Stores the number of candies        var arr = Array(k);         for (i = 0; i < k; i++)            arr[i] = 0;         while (n > 0) {             // Last term of last and            // current series            var f1 = (ind - 1) * k;            var f2 = ind * k;             // Sum of current and last series            var sum1 = (f1 * (f1 + 1)) / 2;            var sum2 = (f2 * (f2 + 1)) / 2;             // Sum of current series only            var res = sum2 - sum1;             // If sum of current is less than N            if (res <= n) {                count++;                n -= res;                ind++;            } else // Individually distribute            {                var i = 0;                 // First term                var term = ((ind - 1) * k) + 1;                 // Distribute candies till there                while (n > 0) {                     // Candies available                    if (term <= n) {                        arr[i++] = term;                        n -= term;                        term++;                    } else // Not available                    {                        arr[i++] = n;                        n = 0;                    }                }            }        }         // Count the total candies        for (i = 0; i < k; i++)            arr[i] += (count * (i + 1)) +            (k * (count * (count - 1)) / 2);         // Print the total candies        for (i = 0; i < k; i++)            document.write(arr[i] + " ");    }     // Driver Code             var n = 10, k = 3;        candies(n, k); // This code contributed by Rajput-Ji </script>
5 2 3
 
Time complexity: O(Number of turns + K)An efficient approach is to find the largest number(say MAXI) whose sum upto natural numbers is less than N using Binary search. Since the last number will always be a multiple of K, we get the last number of complete turns. Subtract the summation till then from N. Distribute the remaining candies by traversing in the array. Below is the implementation of the above approach:  
C++
Java
Python3
C#
PHP
Javascript
// C++ implementation of the above approach#include <bits/stdc++.h>using namespace std; // Function to find out the number of// candies every person receivedvoid candies(int n, int k){     // Count number of complete turns    int count = 0;     // Get the last term    int ind = 1;     // Stores the number of candies    int arr[k];     memset(arr, 0, sizeof(arr));     int low = 0, high = n;     // Do a binary search to find the number whose    // sum is less than N.    while (low <= high) {         // Get mide        int mid = (low + high) >> 1;        int sum = (mid * (mid + 1)) >> 1;         // If sum is below N        if (sum <= n) {             // Find number of complete turns            count = mid / k;             // Right halve            low = mid + 1;        }        else {             // Left halve            high = mid - 1;        }    }     // Last term of last complete series    int last = (count * k);     // Subtract the sum till    n -= (last * (last + 1)) / 2;     int i = 0;     // First term of incomplete series    int term = (count * k) + 1;     while (n) {        if (term <= n) {            arr[i++] = term;            n -= term;            term++;        }        else {            arr[i] += n;            n = 0;        }    }     // Count the total candies    for (int i = 0; i < k; i++)        arr[i] += (count * (i + 1))               + (k * (count * (count - 1)) / 2);     // Print the total candies    for (int i = 0; i < k; i++)        cout << arr[i] << " ";} // Driver Codeint main(){    int n = 7, k = 4;    candies(n, k);     return 0;}
// Java implementation of the above approach class GFG{    // Function to find out the number of    // candies every person received    static void candies(int n, int k)    {             // Count number of complete turns        int count = 0;             // Get the last term        int ind = 1;             // Stores the number of candies        int []arr=new int[k];              for(int i=0;i<k;i++)         arr[i]=0;                   int low = 0, high = n;             // Do a binary search to find the number whose        // sum is less than N.        while (low <= high) {                 // Get mide            int mid = (low + high) >> 1;            int sum = (mid * (mid + 1)) >> 1;                 // If sum is below N            if (sum <= n) {                     // Find number of complete turns                count = mid / k;                     // Right halve                low = mid + 1;            }            else {                     // Left halve                high = mid - 1;            }        }             // Last term of last complete series        int last = (count * k);             // Subtract the sum till        n -= (last * (last + 1)) / 2;             int j = 0;             // First term of incomplete series        int term = (count * k) + 1;             while (n > 0) {            if (term <= n) {                arr[j++] = term;                n -= term;                term++;            }            else {                arr[j] += n;                n = 0;            }        }             // Count the total candies        for (int i = 0; i < k; i++)            arr[i] += (count * (i + 1))                + (k * (count * (count - 1)) / 2);             // Print the total candies        for (int i = 0; i < k; i++)            System.out.print( arr[i] + " " );    }         // Driver Code    public static void main(String []args)    {        int n = 7, k = 4;        candies(n, k);                  } } // This code is contributed by ihritik
# Python3 implementation of the above approach # Function to find out the number of# candies every person receiveddef candies(n, k):     # Count number of complete turns    count = 0;     # Get the last term    ind = 1;     # Stores the number of candies    arr = [0] * k;     low = 0;    high = n;     # Do a binary search to find the    # number whose sum is less than N.    while (low <= high):         # Get mide        mid = (low + high) >> 1;        sum = (mid * (mid + 1)) >> 1;         # If sum is below N        if (sum <= n):             # Find number of complete turns            count = int(mid / k);             # Right halve            low = mid + 1;        else:             # Left halve            high = mid - 1;     # Last term of last complete series    last = (count * k);     # Subtract the sum till    n -= int((last * (last + 1)) / 2);     i = 0;     # First term of incomplete series    term = (count * k) + 1;     while (n):        if (term <= n):            arr[i] = term;            i += 1;            n -= term;            term += 1;        else:            arr[i] += n;            n = 0;     # Count the total candies    for i in range(k):        arr[i] += ((count * (i + 1)) +                int(k * (count * (count - 1)) / 2));     # Print the total candies    for i in range(k):        print(arr[i], end = " "); # Driver Coden = 7;k = 4;candies(n, k); # This code is contributed by chandan_jnu
// C# implementation of the above approach using System;class GFG{    // Function to find out the number of    // candies every person received    static void candies(int n, int k)    {             // Count number of complete turns        int count = 0;             // Get the last term        int ind = 1;             // Stores the number of candies        int []arr=new int[k];              for(int i=0;i<k;i++)         arr[i]=0;                   int low = 0, high = n;             // Do a binary search to find the number whose        // sum is less than N.        while (low <= high) {                 // Get mide            int mid = (low + high) >> 1;            int sum = (mid * (mid + 1)) >> 1;                 // If sum is below N            if (sum <= n) {                     // Find number of complete turns                count = mid / k;                     // Right halve                low = mid + 1;            }            else {                     // Left halve                high = mid - 1;            }        }             // Last term of last complete series        int last = (count * k);             // Subtract the sum till        n -= (last * (last + 1)) / 2;             int j = 0;             // First term of incomplete series        int term = (count * k) + 1;             while (n > 0) {            if (term <= n) {                arr[j++] = term;                n -= term;                term++;            }            else {                arr[j] += n;                n = 0;            }        }             // Count the total candies        for (int i = 0; i < k; i++)            arr[i] += (count * (i + 1))                + (k * (count * (count - 1)) / 2);             // Print the total candies        for (int i = 0; i < k; i++)            Console.Write( arr[i] + " " );    }         // Driver Code    public static void Main()    {        int n = 7, k = 4;        candies(n, k);                  } } // This code is contributed by ihritik
<?php// PHP implementation of the above approach // Function to find out the number of// candies every person receivedfunction candies($n, $k){     // Count number of complete turns    $count = 0;     // Get the last term    $ind = 1;     // Stores the number of candies    $arr = array_fill(0, $k, 0);     $low = 0;    $high = $n;     // Do a binary search to find the    // number whose sum is less than N.    while ($low <= $high)    {         // Get mide        $mid = ($low + $high) >> 1;        $sum = ($mid * ($mid + 1)) >> 1;         // If sum is below N        if ($sum <= $n)        {             // Find number of complete turns            $count = (int)($mid / $k);             // Right halve            $low = $mid + 1;        }        else        {             // Left halve            $high = $mid - 1;        }    }     // Last term of last complete series    $last = ($count * $k);     // Subtract the sum till    $n -= (int)(($last * ($last + 1)) / 2);     $i = 0;     // First term of incomplete series    $term = ($count * $k) + 1;     while ($n)    {        if ($term <= $n)        {            $arr[$i++] = $term;            $n -= $term;            $term++;        }        else        {            $arr[$i] += $n;            $n = 0;        }    }     // Count the total candies    for ($i = 0; $i < $k; $i++)        $arr[$i] += ($count * ($i + 1)) +         (int)($k * ($count * ($count - 1)) / 2);     // Print the total candies    for ($i = 0; $i < $k; $i++)        echo $arr[$i] . " ";} // Driver Code$n = 7;$k = 4;candies($n, $k); // This code is contributed// by chandan_jnu?>
<script>// javascript implementation of the above approach   // Function to find out the number of    // candies every person received    function candies(n , k) {         // Count number of complete turns        var count = 0;         // Get the last term        var ind = 1;         // Stores the number of candies        var arr = Array(k).fill(0);         for (i = 0; i < k; i++)            arr[i] = 0;         var low = 0, high = n;         // Do a binary search to find the number whose        // sum is less than N.        while (low <= high) {             // Get mide            var mid = parseInt((low + high) /2);            var sum = parseInt((mid * (mid + 1)) / 2);             // If sum is below N            if (sum <= n) {                 // Find number of complete turns                count = parseInt(mid / k);                 // Right halve                low = mid + 1;            } else {                 // Left halve                high = mid - 1;            }        }         // Last term of last complete series        var last = (count * k);         // Subtract the sum till        n -= (last * (last + 1)) / 2;         var j = 0;         // First term of incomplete series        var term = (count * k) + 1;         while (n > 0) {            if (term <= n) {                arr[j++] = term;                n -= term;                term++;            } else {                arr[j] += n;                n = 0;            }        }         // Count the total candies        for (i = 0; i < k; i++)            arr[i] += (count * (i + 1)) + (k * (count * (count - 1)) / 2);         // Print the total candies        for (i = 0; i < k; i++)            document.write(arr[i] + " ");    }     // Driver Code             var n = 7, k = 4;        candies(n, k);  // This code contributed by aashish1995</script>
1 2 3 1
 
Time Complexity: O(log N + K) 
ihritik
mohit kumar 29
ankthon
Chandan_Kumar
Rajput-Ji
aashish1995
ankita_saini
tripathikrishnakanttripathi
Binary Search
Mathematical
Mathematical
Binary Search
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Modulo Operator (%) in C/C++ with Examples
Program to find GCD or HCF of two numbers
Merge two sorted arrays
Prime Numbers
Program to find sum of elements in a given array
Program for factorial of a number
Program for Decimal to Binary Conversion
Sieve of Eratosthenes
Operators in C / C++
The Knight's tour problem | Backtracking-1