Little Ashish's Huge Donation
https://www.hackerrank.com/challenges/little-chammys-huge-donation
Problem Statement
Little Ashish is doing internship at multiple places. Instead of giving parties to his friends he decided to donate candies to children. He likes solving puzzles and playing games. Hence he plays a small game. Suppose there are N children. The rules of the game are:
- The
ith child getsi2 candies (1≤i≤N ). - The
yth child cannot get a candy until and unless all the children before him (1≤i<y ) gets candies according to rule number1 .
One of his jealous friends, Pipi, asks him "Given X (the number of candies) how many children will you be able to serve?". Little Ashish fears calculations and cannot solve this problem so he leaves this problem to the worthy programmers of the world. Help little Ashish in finding the solution.
Input Format
The first line containsT i.e. number of test cases.
T lines follow, each line containing an integer X .
The first line contains
Output Format
For each testcase, print the output that little Ashish wants in one line.
For each testcase, print the output that little Ashish wants in one line.
Constraints
1≤T≤10000
1≤X≤1016
Note: If the ith child doesn't get i2 number of candies then it's not counted as a successful donation
Sample Input
3
1
5
13
Sample Output
1
2
2
Explanation
- For
X=1 . Only the1st child can get the candy (i.e.12 candy) and no other child. - For
X=5 . Both the1st (12 candies) and the2nd (22 candies) children can get the candies. - For
X=13 . Since the3rd child will get only 8 candies following the rule it won't be counted as a successful donation. Only the1st and the2nd children can get 1 and 4 candies respectively.
-------------------------------------EDITORIAL-----------------------------
The binary search approach
Consider a list of integers `
`
This list consists of numbers in increasing order.
Now, we want to find the maximum number of children `
Whenever we have a collection (list) which is either in increasing or decreasing order, we can applybinary search to find the numbers which are equal to, greater than, or less than a given number.
The only thing thing that remains is figuring out the details. Look at the following code snippet to get a better idea of the approach (also recommended is checking the setter's code):
def answer(X):
L = 1
R = 1000000 # a really large number which should be
# much greater than the actual answer, i.e.
# S(R) > X
while R - L > 1:
M = (L + R)/2
if S(M) <= X:
L = M
else:
R = M
return L
Note that this function assumes you have already implemented the function Si ` quickly.
S(i) which should return the value `
Addendum: Formula for `Si `
Let us try to find a formula for `
`
`
Now, the number `Ti=∑ij=0j=0+1+2+⋯+i ` is called a triangular number whose formula can be derived as:
`
Back to `Si `:
`
Therefore, `Si ` is just `i(i+1)(2i+1)6 `.
Addendum: Newton's method
We'll describe a faster, more advanced approach which we hope you'll find helpful.
Note that we are finding the largest `
We want to find a solution x of the equation `
`
where `
Now, the derivative of `
`
and finally, `
All of this is implemented in the following code snippet:
def answer(X):
r = pow(3*X, 1/3.) # approximate solution
while True:
nr = r - (r*(r+1)*(2*r+1) - 6*X)/(6*r*(r+1) + 1)
if abs(r - nr) < 1e-6: # converged
return int(nr)
r = nr
------------------------------EDITORIAL------------------------------------
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define test() int test_case;cin>>test_case;while(test_case--)
#define fr(i,n) for(int i=0;i<n;i++)
#define frr(i,a,n) for(int p=i;p<n;p++)
#define sll(a) scanf("%lld",&a)
#define sl(a) scanf("%ld",&a)
#define si(a) scanf("%i",&a)
#define sd(a) scanf("%ld",&a)
#define sf(a) scanf("%f",&a)
#define rn(a) return a
#define pai pair<int,int>
#define pal pair<li,li>
#define pall pair<lli,lli>
#define ff first
#define ss second
#define mod 1000000007
#define mp make_pair
#define pb push_back
#define pll(a) printf("%lld\n",a);
#define pl(a) printf("%lld\n",a);
#define pi(a) printf("%d\n",a);
#define pd(a) printf("%lf\n",a);
#define pf(a) printf("%f\n",a);
lli ans=0;
list<lli> li[1000];
lli visited[10000];
lli func(lli num)
{
return (num*(num+1)*(2*num+1))/6;
}
int main()
{
test()
{
lli x;
lli ans=0;
cin>>x;
lli mini=1;
lli maxi=1000000;
while(mini<maxi)
{
lli mid=(mini+maxi)/2;
if(func(mid)>x)
{
maxi=mid;
}
else
{
ans=max(ans,mid);
mini=mid+1;
}
}
cout<<ans<<endl;
}
return 0;
}
No comments:
Post a Comment