Maximum number of people that can be killed with strength P

There are infinite people standing in a row, indexed from 1. A person having index i has strength of i2. You have strength P and the task is to tell what is the maximum number of people you can kill with strength P.
You can only kill a person with strength X if P ≥ X and after killing him, your strength decreases by X.

Examples:

Input: P = 14
Output: 3
First person will have strength 12 = 1 which is < P
P gets reduced to 13 after the first kill.
Second kill, P = 13 – 22 = 9
Third kill, P = 9 – 32 = 0

Input: P = 58
Output: 5

Naive approach: Check every single kill starting from 1 until the strength P is greater than or equal to the strength of the person being killed.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to return the maximum
// number of people that can be killed
int maxPeople(int p)
{
    int tmp = 0, count = 0;
  
    // Loop will break when the ith person
    // cannot be killed
    for (int i = 1; i * i <= p; i++) {
        tmp = tmp + (i * i);
        if (tmp <= p)
            count++;
        else
            break;
    }
    return count;
}
  
// Driver code
int main()
{
    int p = 14;
    cout << maxPeople(p);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
import java.util.*;
  
class GFG
{    
// Function to return the maximum
// number of people that can be killed
static int maxPeople(int p)
{
    int tmp = 0, count = 0;
  
    // Loop will break when the ith person
    // cannot be killed
    for (int i = 1; i * i <= p; i++) 
    {
        tmp = tmp + (i * i);
        if (tmp <= p)
            count++;
        else
            break;
    }
    return count;
}
  
// Driver code
public static void main(String args[])
{
    int p = 14;
    System.out.println(maxPeople(p));
  
}
}
  
// This code is contributed by Arnab Kundu

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach 
  
from math import sqrt
  
# Function to return the maximum 
# number of people that can be killed 
def maxPeople(p) : 
      
    tmp = 0; count = 0
  
    # Loop will break when the ith person 
    # cannot be killed 
    for i in range(1, int(sqrt(p)) + 1) :
        tmp = tmp + (i * i); 
        if (tmp <= p) :
            count += 1
        else :
            break
      
    return count; 
  
  
# Driver code 
if __name__ == "__main__"
  
    p = 14
    print(maxPeople(p)); 
      
# This code is contributed by AnkitRai01

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;
  
class GFG
      
// Function to return the maximum
// number of people that can be killed
static int maxPeople(int p)
{
    int tmp = 0, count = 0;
  
    // Loop will break when the ith person
    // cannot be killed
    for (int i = 1; i * i <= p; i++) 
    {
        tmp = tmp + (i * i);
        if (tmp <= p)
            count++;
        else
            break;
    }
    return count;
}
  
// Driver code
public static void Main()
{
    int p = 14;
    Console.WriteLine(maxPeople(p));
}
}
  
// This code is contributed by anuj_67..

chevron_right


Output:

3

Time Complexity: O(N)

Efficient approach: We can see if we kill ith person then we have already killed (i – 1)th person. This means it is a monotonic function f whose domain is the set of integers. Now we can apply binary search on this monotonic function in which instead of array lookup we are now looking for some x such that f(x) is equal to the target value. Time complexity reduces to O(Log(n)).

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ implementation of the approach
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
  
static constexpr int kN = 1000000;
  
// Function to return the maximum
// number of people that can be killed
int maxPeople(int p)
{
    // Storing the sum beforehand so that
    // it can be used in each query
    ll sums[kN];
    sums[0] = 0;
    for (int i = 1; i < kN; i++)
        sums[i] = (ll)(i * i) + sums[i - 1];
  
    // lower_bound returns an iterator pointing to the
    // first element greater than or equal to your val
    auto it = std::lower_bound(sums, sums + kN, p);
    if (*it > p) {
  
        // Previous value
        --it;
    }
  
    // Returns the index in array upto which
    // killing is possible with strength P
    return (it - sums);
}
  
// Driver code
int main()
{
    int p = 14;
    cout << maxPeople(p);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java implementation of the approach
class GFG
{
  
static int kN = 1000000;
  
// Function to return the maximum
// number of people that can be killed
static int maxPeople(int p)
{
    // Storing the sum beforehand so that
    // it can be used in each query
    long []sums = new long[kN];
    sums[0] = 0;
    for (int i = 1; i < kN; i++)
        sums[i] = (long)(i * i) + sums[i - 1];
  
    // lower_bound returns an iterator pointing to the
    // first element greater than or equal to your val
    int it = lower_bound(sums, 0, kN, p);
    if (it > p) 
    {
  
        // Previous value
        --it;
    }
  
    // Returns the index in array upto which
    // killing is possible with strength P
    return it;
}
private static int lower_bound(long[] a, int low, 
                            int high, int element)
{
    while(low < high)
    {
        int middle = low + (high - low)/2;
        if(element > a[middle])
            low = middle + 1;
        else
            high = middle;
    }
    return low;
}
  
// Driver code
public static void main(String[] args)
{
    int p = 14;
    System.out.println(maxPeople(p));
}
}
  
/* This code is contributed by PrinciRaj1992 */

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 implementation of the approach
kN = 1000000;
  
# Function to return the maximum
# number of people that can be killed
def maxPeople(p):
  
    # Storing the sum beforehand so that
    # it can be used in each query
    sums = [0] * kN;
    sums[0] = 0;
    for i in range(1, kN):
        sums[i] = (i * i) + sums[i - 1];
  
    # lower_bound returns an iterator 
    # pointing to the first element 
    # greater than or equal to your val
    it = lower_bound(sums, 0, kN, p);
    if (it > p):
  
        # Previous value
        it -= 1;
  
    # Returns the index in array upto which
    # killing is possible with strength P
    return it;
  
def lower_bound(a, low, high, element):
    while(low < high):
        middle = int(low + (high - low) / 2);
        if(element > a[middle]):
            low = middle + 1;
        else:
            high = middle;
    return low;
  
# Driver code
if __name__ == '__main__':
    p = 14;
    print(maxPeople(p));
  
# This code contributed by Rajput-Ji

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# implementation of the approach
using System;     
      
public class GFG
{
  
static int kN = 1000000;
  
// Function to return the maximum
// number of people that can be killed
static int maxPeople(int p)
{
    // Storing the sum beforehand so that
    // it can be used in each query
    long []sums = new long[kN];
    sums[0] = 0;
    for (int i = 1; i < kN; i++)
        sums[i] = (long)(i * i) + sums[i - 1];
  
    // lower_bound returns an iterator pointing to the
    // first element greater than or equal to your val
    int it = lower_bound(sums, 0, kN, p);
    if (it > p) 
    {
  
        // Previous value
        --it;
    }
  
    // Returns the index in array upto which
    // killing is possible with strength P
    return it;
}
private static int lower_bound(long[] a, int low, 
                            int high, int element)
{
    while(low < high)
    {
        int middle = low + (high - low)/2;
        if(element > a[middle])
            low = middle + 1;
        else
            high = middle;
    }
    return low;
}
  
// Driver code
public static void Main(String[] args)
{
    int p = 14;
    Console.WriteLine(maxPeople(p));
}
}
  
// This code has been contributed by 29AjayKumar

chevron_right


Output:

3

Time Complexity: O(Log(n))



My Personal Notes arrow_drop_up

Competitive Programmer, Full Stack Developer

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.