Given a tank with capacity C liters which is completely filled in starting. Everyday tank is filled with l liters of water and in the case of overflow extra water is thrown out. Now on i-th day i liters of water is taken out for drinking. We need to find out the day at which tank will become empty the first time.
Examples:
Input : Capacity = 5
l = 2
Output : 4
At the start of 1st day, water in tank = 5
and at the end of the 1st day = (5 - 1) = 4
At the start of 2nd day, water in tank = 4 + 2 = 6
but tank capacity is 5 so water = 5
and at the end of the 2nd day = (5 - 2) = 3
At the start of 3rd day, water in tank = 3 + 2 = 5
and at the end of the 3rd day = (5 - 3) = 2
At the start of 4th day, water in tank = 2 + 2 = 4
and at the end of the 4th day = (4 - 4) = 0
So final answer will be 4
We can see that tank will be full for starting (l + 1) days because water taken out is less than water being filled. After that, each day water in the tank will be decreased by 1 more liter and on (l + 1 + i)th day (C – (i)(i + 1) / 2) liter water will remain before taking drinking water.
Now we need to find a minimal day (l + 1 + K), in which even after filling the tank by l liters we have water less than l in tank i.e. on (l + 1 + K – 1)th day tank becomes empty so our goal is to find minimum K such that,
C – K(K + 1) / 2 <= l
We can solve above equation using binary search and then (l + K) will be our answer. Total time complexity of solution will be O(log C)
C++
#include <bits/stdc++.h>
using namespace std;
int getCumulateSum( int n)
{
return (n * (n + 1)) / 2;
}
int minDaysToEmpty( int C, int l)
{
if (C <= l)
return C;
int lo = 0;
int hi = 1e4;
int mid;
while (lo < hi) {
mid = (lo + hi) / 2;
if (getCumulateSum(mid) >= (C - l))
hi = mid;
else
lo = mid + 1;
}
return (l + lo);
}
int main()
{
int C = 5;
int l = 2;
cout << minDaysToEmpty(C, l) << endl;
return 0;
}
|
Java
public class Tank_Empty {
static int getCumulateSum( int n)
{
return (n * (n + 1 )) / 2 ;
}
static int minDaysToEmpty( int C, int l)
{
if (C <= l)
return C;
int lo = 0 ;
int hi = ( int )1e4;
int mid;
while (lo < hi) {
mid = (lo + hi) / 2 ;
if (getCumulateSum(mid) >= (C - l))
hi = mid;
else
lo = mid + 1 ;
}
return (l + lo);
}
public static void main(String args[])
{
int C = 5 ;
int l = 2 ;
System.out.println(minDaysToEmpty(C, l));
}
}
|
Python3
def getCumulateSum(n):
return int ((n * (n + 1 )) / 2 )
def minDaysToEmpty(C, l):
if (C < = l) : return C
lo, hi = 0 , 1e4
while (lo < hi):
mid = int ((lo + hi) / 2 )
if (getCumulateSum(mid) > = (C - l)):
hi = mid
else :
lo = mid + 1
return (l + lo)
C, l = 5 , 2
print (minDaysToEmpty(C, l))
|
C#
using System;
class GFG
{
static int getCumulateSum( int n)
{
return (n * (n + 1)) / 2;
}
static int minDaysToEmpty( int C,
int l)
{
if (C <= l)
return C;
int lo = 0;
int hi = ( int )1e4;
int mid;
while (lo < hi)
{
mid = (lo + hi) / 2;
if (getCumulateSum(mid) >= (C - l))
hi = mid;
else
lo = mid + 1;
}
return (l + lo);
}
static public void Main ()
{
int C = 5;
int l = 2;
Console.WriteLine(minDaysToEmpty(C, l));
}
}
|
Javascript
<script>
function getCumulateSum(n)
{
return parseInt((n * (n + 1)) / 2, 10);
}
function minDaysToEmpty(C, l)
{
if (C <= l)
return C;
let lo = 0;
let hi = 1e4;
let mid;
while (lo < hi)
{
mid = parseInt((lo + hi) / 2, 10);
if (getCumulateSum(mid) >= (C - l))
hi = mid;
else
lo = mid + 1;
}
return (l + lo);
}
let C = 5;
let l = 2;
document.write(minDaysToEmpty(C, l));
</script>
|
Output:
4
Alternate Solution :
It can be solved mathematically with a simple formula:
Let’s Assume C>L. Let d be the amount of days after the Lth when the tank become empty.During that time, there will be (d-1)refills and d withdrawals.
Hence we need to solve this equation :

Sum of all withdrawals is a sum of arithmetic progression,therefore :



Discriminant = 1+8(C-L)>0,because C>L.
Skipping the negative root, we get the following formula:

Therefore, the final answer is:

C++
#include <bits/stdc++.h>
using namespace std;
int minDaysToEmpty( int C, int l)
{
if (l >= C)
return C;
double eq_root = (std:: sqrt (1+8*(C-l)) - 1) / 2;
return std:: ceil (eq_root) + l;
}
int main()
{
cout << minDaysToEmpty(5, 2) << endl;
cout << minDaysToEmpty(6514683, 4965) << endl;
return 0;
}
|
Java
import java.lang.*;
class GFG {
static int minDaysToEmpty( int C, int l)
{
if (l >= C) return C;
double eq_root = (Math.sqrt( 1 + 8 *
(C - l)) - 1 ) / 2 ;
return ( int )(Math.ceil(eq_root) + l);
}
public static void main(String[] args)
{
System.out.println(minDaysToEmpty( 5 , 2 ));
System.out.println(minDaysToEmpty( 6514683 , 4965 ));
}
}
|
Python3
import math
def minDaysToEmpty(C, l):
if (l > = C): return C
eq_root = (math.sqrt( 1 + 8 * (C - l)) - 1 ) / 2
return math.ceil(eq_root) + l
print (minDaysToEmpty( 5 , 2 ))
print (minDaysToEmpty( 6514683 , 4965 ))
|
C#
using System;
class GFG
{
static int minDaysToEmpty( int C,
int l)
{
if (l >= C) return C;
double eq_root = (Math.Sqrt(1 + 8 *
(C - l)) - 1) / 2;
return ( int )(Math.Ceiling(eq_root) + l);
}
static public void Main ()
{
Console.WriteLine(minDaysToEmpty(5, 2));
Console.WriteLine(minDaysToEmpty(6514683,
4965));
}
}
|
PHP
<?php
function minDaysToEmpty( $C , $l )
{
if ( $l >= $C )
return $C ;
$eq_root = (int)sqrt(1 + 8 *
( $C - $l ) - 1) / 2;
return ceil ( $eq_root ) + $l ;
}
echo minDaysToEmpty(5, 2), "\n" ;
echo minDaysToEmpty(6514683,
4965), "\n" ;
?>
|
Javascript
<script>
function minDaysToEmpty(C, l)
{
if (l >= C) return C;
let eq_root = (Math.sqrt(1 + 8 *
(C - l)) - 1) / 2;
return (Math.ceil(eq_root) + l);
}
document.write(minDaysToEmpty(5, 2) + "</br>" );
document.write(minDaysToEmpty(6514683, 4965));
</script>
|
Output :
4
8573
Thanks to Andrey Khayrutdinov for suggesting this solution.
If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
31 Oct, 2022
Like Article
Save Article