📌  相关文章
📜  在K人中分配N个糖果

📅  最后修改于: 2021-04-23 20:37:32             🧑  作者: Mango

给定N个糖果和K个人。在第一个回合中,第一个人获得1个糖果,第二个人获得2个糖果,依此类推,直到K个人为止。在下一回合中,第一个人获得K + 1个糖果,第二个人获得k + 2个糖果,依此类推。如果糖果的数量每次转动都少于所需的糖果数量,则该人会收到剩余的糖果数量。

任务是找到每个人最后拥有的糖果总数。

例子:

天真的方法是每回合迭代并相应地分配糖果,直到糖果完成。
时间复杂度: O(分布数)

一种更好的方法是通过计算直到序列的最后一项将是(turns * k)的自然数之和并减去直到上一个序列的最后一项是( )的自然数之和来执行O(1)的每一转。转1)* k。继续这样做,直到总和小于N,一旦超过总和,就以给定的方式分配糖果,直到可能为止。如果每个人都能获得所需的转弯数量的糖果,我们将转弯称为完成转弯。

下面是上述方法的实现:

C++
// C++ code for better approach
// to distribute candies
#include 
using namespace std;
  
// Function to find out the number of
// candies every person received
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[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 Code
int main()
{
    int n = 10, k = 3;
    candies(n, k);
  
    return 0;
}


Java
// 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)
    {
      
        // 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;i0) {
      
            // 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++)
            System.out.print( arr[i] + " ");
    }
      
    // Driver Code
    public static void main(String []args)
    {
        int n = 10, k = 3;
        candies(n, k);
      
          
    }
}
  
  
// This code is contributed by ihritik


Python3
# Python3 code for better approach
# to distribute candies
import math as mt
  
# Function to find out the number of
# candies every person received
def 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 Code
n, k = 10, 3
candies(n, k)
  
# This code is contributed by Mohit kumar


C#
// 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;i0) {
      
            // 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
 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
?>


C++
// C++ implementation of the above approach
#include 
using namespace std;
  
// Function to find out the number of
// candies every person received
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[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 Code
int main()
{
    int n = 7, k = 4;
    candies(n, k);
  
    return 0;
}


Java
// 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> 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
# Python3 implementation of the above approach
  
# Function to find out the number of
# candies every person received
def 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 Code
n = 7;
k = 4;
candies(n, k);
  
# This code is contributed by chandan_jnu


C#
// 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> 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
> 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
?>


输出:
5 2 3

时间复杂度: O(匝数+ K)

一种有效的方法是使用二进制搜索来找到最大自然数之和小于N的最大数(例如MAXI)。由于最后一个数字将始终是K的倍数,因此我们得到了完整回合的最后一个数字。从N减去之前的总和。通过遍历数组分布剩余的糖果。

下面是上述方法的实现:

C++

// C++ implementation of the above approach
#include 
using namespace std;
  
// Function to find out the number of
// candies every person received
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[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 Code
int main()
{
    int n = 7, k = 4;
    candies(n, k);
  
    return 0;
}

Java

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

# Python3 implementation of the above approach
  
# Function to find out the number of
# candies every person received
def 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 Code
n = 7;
k = 4;
candies(n, k);
  
# This code is contributed by chandan_jnu

C#

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

> 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
?>
输出:
1 2 3 1

时间复杂度: O(log N + K)