HDU-P2289:Cup[二分答案+数学]
HDU-P2289:Cup[二分答案+数学]
题目
Problem Description
The WHU ACM Team has a big cup, with which every member drinks water. Now, we know the volume of the water in the cup, can you tell us it height?
The radius of the cup’s top and bottom circle is known, the cup’s height is also known.
Input
The input consists of several test cases. The first line of input contains an integer T, indicating the num of test cases.
Each test case is on a single line, and it consists of four floating point numbers: r, R, H, V, representing the bottom radius, the top radius, the height and the volume of the hot water.
Technical Specification
- T ≤ 20.
- 1 ≤ r, R, H ≤ 100; 0 ≤ V ≤ 1000,000,000.
- r ≤ R.
- r, R, H, V are separated by ONE whitespace.
- There is NO empty line between two neighboring cases.
Output
For each test case, output the height of hot water on a single line. Please round it to six fractional digits.
Sample Input
1
100 100 100 3141562
Sample Output
99.999024
思路
台体的计算公式为V = (1/3)h*(s1+s2+sqrt(s1*s2)),再根据简单的中学知识可以得到一个一元三次方程,解出方程即可。
解方程时由于一元三次的方程式的求根公式并不好直接使用,所以采用二分法对方程进行求解,由于一元三次方程式最多有可能有三个解,所以我们要确定二分的范围,根据题目的意思我们可以知道范围为0~H,在此范围内进行二分即可。
代码
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double PI = acos(-1.0);
int main(void)
{
int T; scanf("%d", &T);
double r, R, H, V;
double mid;
while(T--) {
scanf("%lf%lf%lf%lf", &r, &R, &H, &V);
double low = 0, high = H;
while(high - low > 1e-9) {
mid = (low+high)/2;
double rr = (R-r)*mid/H+r;
double v = PI/3*mid*(r*r+rr*rr+rr*r);
if(fabs(v-V) <= 1e-9)
break;
else if(v>V)
high=mid-1e-9;
else low=mid+1e-9;
}
printf("%.6lf\n", mid);
}
return 0;
}
浙公网安备 33010602011771号