给定容量为C升的油箱,该油箱在启动时已完全充满。每天的水箱中都装有1升水,万一发生溢流,多余的水就会倒出。现在,在第i天,我要取出几公升的水来饮用。我们需要找出罐第一次变空的日期。
例子:
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
我们可以看到水箱在开始(l +1)天将充满,因为取出的水少于注入的水。此后,水箱中的水每天将减少1升,并且在第(l +1 + i)天(C –(i)(i +1)/ 2)升水将被保留,不能再喝水。
现在我们需要找到一个最小的天数(l +1 + K),其中即使在将水箱注满l升后,水箱中的水也少于l,即在第(l +1 + K – 1)天,水箱变空了所以我们的目标是找到最小的K,这样,
C – K(K +1)/ 2 <= l
我们可以使用二进制搜索来求解上述方程,然后(l + K)将是我们的答案。解决方案的总时间复杂度将为O(log C)
C++
// C/C++ code to find number of days after which
// tank will become empty
#include
using namespace std;
// Utility method to get sum of first n numbers
int getCumulateSum(int n)
{
return (n * (n + 1)) / 2;
}
// Method returns minimum number of days after
// which tank will become empty
int minDaysToEmpty(int C, int l)
{
// if water filling is more than capacity then
// after C days only tank will become empty
if (C <= l)
return C;
// initialize binary search variable
int lo = 0;
int hi = 1e4;
int mid;
// loop until low is less than high
while (lo < hi) {
mid = (lo + hi) / 2;
// if cumulate sum is greater than (C - l)
// then search on left side
if (getCumulateSum(mid) >= (C - l))
hi = mid;
// if (C - l) is more then search on
// right side
else
lo = mid + 1;
}
// final answer will be obtained by adding
// l to binary search result
return (l + lo);
}
// Driver code to test above methods
int main()
{
int C = 5;
int l = 2;
cout << minDaysToEmpty(C, l) << endl;
return 0;
}
Java
// Java code to find number of days after which
// tank will become empty
public class Tank_Empty {
// Utility method to get sum of first n numbers
static int getCumulateSum(int n)
{
return (n * (n + 1)) / 2;
}
// Method returns minimum number of days after
// which tank will become empty
static int minDaysToEmpty(int C, int l)
{
// if water filling is more than capacity then
// after C days only tank will become empty
if (C <= l)
return C;
// initialize binary search variable
int lo = 0;
int hi = (int)1e4;
int mid;
// loop until low is less than high
while (lo < hi) {
mid = (lo + hi) / 2;
// if cumulate sum is greater than (C - l)
// then search on left side
if (getCumulateSum(mid) >= (C - l))
hi = mid;
// if (C - l) is more then search on
// right side
else
lo = mid + 1;
}
// final answer will be obtained by adding
// l to binary search result
return (l + lo);
}
// Driver code to test above methods
public static void main(String args[])
{
int C = 5;
int l = 2;
System.out.println(minDaysToEmpty(C, l));
}
}
// This code is contributed by Sumit Ghosh
Python3
# Python3 code to find number of days
# after which tank will become empty
# Utility method to get
# sum of first n numbers
def getCumulateSum(n):
return int((n * (n + 1)) / 2)
# Method returns minimum number of days
# after which tank will become empty
def minDaysToEmpty(C, l):
# if water filling is more than
# capacity then after C days only
# tank will become empty
if (C <= l) : return C
# initialize binary search variable
lo, hi = 0, 1e4
# loop until low is less than high
while (lo < hi):
mid = int((lo + hi) / 2)
# if cumulate sum is greater than (C - l)
# then search on left side
if (getCumulateSum(mid) >= (C - l)):
hi = mid
# if (C - l) is more then
# search on right side
else:
lo = mid + 1
# Final answer will be obtained by
# adding l to binary search result
return (l + lo)
# Driver code
C, l = 5, 2
print(minDaysToEmpty(C, l))
# This code is contributed by Smitha Dinesh Semwal.
C#
// C# code to find number
// of days after which
// tank will become empty
using System;
class GFG
{
// Utility method to get
// sum of first n numbers
static int getCumulateSum(int n)
{
return (n * (n + 1)) / 2;
}
// Method returns minimum
// number of days after
// which tank will become empty
static int minDaysToEmpty(int C,
int l)
{
// if water filling is more
// than capacity then after
// C days only tank will
// become empty
if (C <= l)
return C;
// initialize binary
// search variable
int lo = 0;
int hi = (int)1e4;
int mid;
// loop until low is
// less than high
while (lo < hi)
{
mid = (lo + hi) / 2;
// if cumulate sum is
// greater than (C - l)
// then search on left side
if (getCumulateSum(mid) >= (C - l))
hi = mid;
// if (C - l) is more then
// search on right side
else
lo = mid + 1;
}
// final answer will be
// obtained by adding
// l to binary search result
return (l + lo);
}
// Driver code
static public void Main ()
{
int C = 5;
int l = 2;
Console.WriteLine(minDaysToEmpty(C, l));
}
}
// This code is contributed by ajit
C++
// C/C++ code to find number of days after which
// tank will become empty
#include
using namespace std;
// Method returns minimum number of days after
// which tank will become empty
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;
}
// Driver code to test above methods
int main()
{
cout << minDaysToEmpty(5, 2) << endl;
cout << minDaysToEmpty(6514683, 4965) << endl;
return 0;
}
Java
// Java code to find number of days
// after which tank will become empty
import java.lang.*;
class GFG {
// Method returns minimum number of days
// after which tank will become empty
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);
}
// Driver code
public static void main(String[] args)
{
System.out.println(minDaysToEmpty(5, 2));
System.out.println(minDaysToEmpty(6514683, 4965));
}
}
// This code is contributed by Smitha Dinesh Semwal.
Python3
# Python3 code to find number of days
# after which tank will become empty
import math
# Method returns minimum number of days
# after which tank will become empty
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
# Driver code
print(minDaysToEmpty(5, 2))
print(minDaysToEmpty(6514683, 4965))
# This code is contributed by Smitha Dinesh Semwal.
C#
// C# code to find number
// of days after which
// tank will become empty
using System;
class GFG
{
// Method returns minimum
// number of days after
// which tank will become empty
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);
}
// Driver code
static public void Main ()
{
Console.WriteLine(minDaysToEmpty(5, 2));
Console.WriteLine(minDaysToEmpty(6514683,
4965));
}
}
// This code is contributed by ajit
PHP
= $C)
return $C;
$eq_root = (int)sqrt(1 + 8 *
($C - $l) - 1) / 2;
return ceil($eq_root) + $l;
}
// Driver code
echo minDaysToEmpty(5, 2), "\n";
echo minDaysToEmpty(6514683,
4965), "\n";
// This code is contributed
// by akt_mit
?>
输出:
4
替代解决方案:
可以用一个简单的公式在数学上求解:
假设C> L。设d为第L次储罐倒空后的天数,在此期间将进行(d-1)次加注和d次抽出。
因此,我们需要解决这个方程:
所有提款的总和是算术级数的总和,因此:
判别= 1 + 8(CL)> 0,因为C> L。
跳过负根,我们得到以下公式:
因此,最后的允许条件是:
C++
// C/C++ code to find number of days after which
// tank will become empty
#include
using namespace std;
// Method returns minimum number of days after
// which tank will become empty
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;
}
// Driver code to test above methods
int main()
{
cout << minDaysToEmpty(5, 2) << endl;
cout << minDaysToEmpty(6514683, 4965) << endl;
return 0;
}
Java
// Java code to find number of days
// after which tank will become empty
import java.lang.*;
class GFG {
// Method returns minimum number of days
// after which tank will become empty
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);
}
// Driver code
public static void main(String[] args)
{
System.out.println(minDaysToEmpty(5, 2));
System.out.println(minDaysToEmpty(6514683, 4965));
}
}
// This code is contributed by Smitha Dinesh Semwal.
Python3
# Python3 code to find number of days
# after which tank will become empty
import math
# Method returns minimum number of days
# after which tank will become empty
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
# Driver code
print(minDaysToEmpty(5, 2))
print(minDaysToEmpty(6514683, 4965))
# This code is contributed by Smitha Dinesh Semwal.
C#
// C# code to find number
// of days after which
// tank will become empty
using System;
class GFG
{
// Method returns minimum
// number of days after
// which tank will become empty
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);
}
// Driver code
static public void Main ()
{
Console.WriteLine(minDaysToEmpty(5, 2));
Console.WriteLine(minDaysToEmpty(6514683,
4965));
}
}
// This code is contributed by ajit
的PHP
= $C)
return $C;
$eq_root = (int)sqrt(1 + 8 *
($C - $l) - 1) / 2;
return ceil($eq_root) + $l;
}
// Driver code
echo minDaysToEmpty(5, 2), "\n";
echo minDaysToEmpty(6514683,
4965), "\n";
// This code is contributed
// by akt_mit
?>
输出 :
4
8573
感谢Andrey Khayrutdinov提出了此解决方案。