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
Explanation: 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++
#include <bits/stdc++.h>
using namespace std;
int maxPeople( int p)
{
int tmp = 0, count = 0;
for ( int i = 1; i * i <= p; i++) {
tmp = tmp + (i * i);
if (tmp <= p)
count++;
else
break ;
}
return count;
}
int main()
{
int p = 14;
cout << maxPeople(p);
return 0;
}
|
C
#include <stdio.h>
int maxPeople( int p)
{
int tmp = 0, count = 0;
for ( int i = 1; i * i <= p; i++) {
tmp = tmp + (i * i);
if (tmp <= p)
count++;
else
break ;
}
return count;
}
int main()
{
int p = 14;
printf ( "%d" , maxPeople(p));
return 0;
}
|
Java
import java.util.*;
class GFG {
static int maxPeople( int p)
{
int tmp = 0 , count = 0 ;
for ( int i = 1 ; i * i <= p; i++) {
tmp = tmp + (i * i);
if (tmp <= p)
count++;
else
break ;
}
return count;
}
public static void main(String args[])
{
int p = 14 ;
System.out.println(maxPeople(p));
}
}
|
Python3
from math import sqrt
def maxPeople(p) :
tmp = 0 ; count = 0 ;
for i in range ( 1 , int (sqrt(p)) + 1 ) :
tmp = tmp + (i * i);
if (tmp < = p) :
count + = 1 ;
else :
break ;
return count;
if __name__ = = "__main__" :
p = 14 ;
print (maxPeople(p));
|
C#
using System;
class GFG
{
static int maxPeople( int p)
{
int tmp = 0, count = 0;
for ( int i = 1; i * i <= p; i++)
{
tmp = tmp + (i * i);
if (tmp <= p)
count++;
else
break ;
}
return count;
}
public static void Main()
{
int p = 14;
Console.WriteLine(maxPeople(p));
}
}
|
Javascript
<script>
function maxPeople(p)
{
var tmp = 0, count = 0;
for ( var i = 1; i * i <= p; i++)
{
tmp = tmp + (i * i);
if (tmp <= p)
count++;
else
break ;
}
return count;
}
var p = 14;
document.write(maxPeople(p));
</script>
|
Time Complexity: O(sqrt(N)), where N is the initial strength.
Auxiliary Space: O(1)
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++
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
static constexpr int kN = 1000000;
int maxPeople( int p)
{
ll sums[kN];
sums[0] = 0;
for ( int i = 1; i < kN; i++)
sums[i] = (ll)(i * i) + sums[i - 1];
auto it = std::lower_bound(sums, sums + kN, p);
if (*it > p) {
--it;
}
return (it - sums);
}
int main()
{
int p = 14;
cout << maxPeople(p);
return 0;
}
|
Java
class GFG
{
static int kN = 1000000 ;
static int maxPeople( int p)
{
long []sums = new long [kN];
sums[ 0 ] = 0 ;
for ( int i = 1 ; i < kN; i++)
sums[i] = ( long )(i * i) + sums[i - 1 ];
int it = lower_bound(sums, 0 , kN, p);
if (sums[it] > p)
{
--it;
}
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;
}
public static void main(String[] args)
{
int p = 14 ;
System.out.println(maxPeople(p));
}
}
|
Python3
kN = 1000000 ;
def maxPeople(p):
sums = [ 0 ] * kN;
sums[ 0 ] = 0 ;
for i in range ( 1 , kN):
sums[i] = (i * i) + sums[i - 1 ];
it = lower_bound(sums, 0 , kN, p);
if (it > p):
it - = 1 ;
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;
if __name__ = = '__main__' :
p = 14 ;
print (maxPeople(p));
|
C#
using System;
public class GFG
{
static int kN = 1000000;
static int maxPeople( int p)
{
long []sums = new long [kN];
sums[0] = 0;
for ( int i = 1; i < kN; i++)
sums[i] = ( long )(i * i) + sums[i - 1];
int it = lower_bound(sums, 0, kN, p);
if (it > p)
{
--it;
}
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;
}
public static void Main(String[] args)
{
int p = 14;
Console.WriteLine(maxPeople(p));
}
}
|
Javascript
<script>
const kN = 1000000;
function maxPeople(p)
{
let sums = new Array(kN);
sums[0] = 0;
for (let i = 1; i < kN; i++)
sums[i] = (i * i) + sums[i - 1];
let it = lower_bound(sums, 0, kN, p);
if (it > p) {
--it;
}
return it;
}
function lower_bound(a, low, high, element)
{
while (low < high)
{
let middle = low + parseInt((high - low)/2);
if (element > a[middle])
low = middle + 1;
else
high = middle;
}
return low;
}
let p = 14;
document.write(maxPeople(p));
</script>
|
Time Complexity: O(1000000)
Auxiliary Space: O(1000000)
More Efficient Approach :
We can do the same problem in time complexity O(logn) and Space Complexity in O(1). Start your binary search by considering the value of low as 0 and high as 10^15. We will calculate the mid-value and according to mid, we will change the position of low and high.
Below is the implementation of the above approach.
C++
#include <algorithm>
#include <bits/stdc++.h>
using namespace std;
long squareSeries( long n)
{
return (n * (n + 1) * (2 * n + 1)) / 6;
}
long maxPeople( long n)
{
long low = 0;
long high = 1000000L;
long ans = 0L;
while (low <= high)
{
long mid = low + ((high - low) / 2);
long value = squareSeries(mid);
if (value <= n)
{
ans = mid;
low = mid + 1;
}
else
{
high = mid - 1;
}
}
return ans;
}
int main()
{
long p = 14;
cout<<maxPeople(p);
return 0;
}
|
Java
class GFG{
static long squareSeries( long n)
{
return (n * (n + 1 ) * ( 2 * n + 1 )) / 6 ;
}
static long maxPeople( long n)
{
long low = 0 ;
long high = 1000000L;
long ans = 0L;
while (low <= high)
{
long mid = low + ((high - low) / 2 );
long value = squareSeries(mid);
if (value <= n)
{
ans = mid;
low = mid + 1 ;
}
else
{
high = mid - 1 ;
}
}
return ans;
}
public static void main(String[] args)
{
long p = 14 ;
System.out.println(maxPeople(p));
}}
|
Python3
def squareSeries(n):
return (n * (n + 1 ) * ( 2 * n + 1 )) / / 6
def maxPeople(n):
low = 0
high = 1000000000000000
while low< = high:
mid = low + ((high - low) / / 2 )
value = squareSeries(mid)
if value< = n:
ans = mid
low = mid + 1
else :
high = mid - 1
return ans
if __name__ = = '__main__' :
p = 14
print (maxPeople(p))
|
C#
using System;
class GFG{
static long squareSeries( long n)
{
return (n * (n + 1) * (2 * n + 1)) / 6;
}
static long maxPeople( long n)
{
long low = 0;
long high = 1000000L;
long ans = 0L;
while (low <= high)
{
long mid = low + ((high - low) / 2);
long value = squareSeries(mid);
if (value <= n)
{
ans = mid;
low = mid + 1;
}
else
{
high = mid - 1;
}
}
return ans;
}
public static void Main(String[] args)
{
long p = 14;
Console.Write(maxPeople(p));
}}
|
Javascript
<script>
function squareSeries(n)
{
return Math.floor((n * (n + 1) * (2 * n + 1)) / 6);
}
function maxPeople(n)
{
let low = 0;
let high = 1000000;
let ans = 0;
while (low <= high)
{
let mid = low + Math.floor((high - low) / 2);
let value = squareSeries(mid);
if (value <= n)
{
ans = mid;
low = mid + 1;
}
else
{
high = mid - 1;
}
}
return ans;
}
let p = 14;
document.write(maxPeople(p));
</script>
|
Time Complexity: O(Log(1000000))
Auxiliary Space: O(1)
Last Updated :
02 Aug, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...