HDU 2289 Cup

来源:互联网 发布:c语言中=和==的区别 编辑:程序博客网 时间:2024/06/05 08:20

题目:

Description

一个杯子装了很多水,可以把杯子看成圆台,并给出圆台的底面半径,顶部半径,高还有水的体积,求水的高度。

Input

输入包括T组数据 
每组数据包含一行,并且有四个数r, R, H, V代表圆台底部半径,顶部半径,高度和水的体积。 

1. T ≤ 20. 
2. 1 ≤ r, R, H ≤ 100; 0 ≤ V ≤ 1000,000,000. 
3. r ≤ R. 
4. r, R, H, V 输入 
5. 无空数据

Output

答案为一行,保留6位小数

Sample Input

1
100 100 100 3141562 

Sample Output

99.999024 

我是先按照正常的思路来做的,如果是R==r,也就是圆柱,直接用体积除以底面积就是的了。

否则的话,首先把圆台补齐成大圆锥,补出来的小圆锥的高为h=H*r/(R-r)

最后要求的高设为x,那么x应该满足3*v*h*h=Pi*r*r* (  (x+h)^3-h^3  )

那么x可以直接求出来。

但是,因为h是有分母的,当R和r非常接近时,x的误差是无法估量的。

所以,只能把上面的表达式的h代入,然后继续化简,变成整式,即3*v*H*H = Pi * x * (x*x*(R-r)*(R-r)+3*x*H*r*(R-r)+3*H*H*r*r)

然后直接求它的零点就OK了。

代码:

#include<stdio.h>#include<math.h>int main(){int t;scanf("%d", &t);double r,R,H,v;while (t--){scanf("%lf%lf%lf%lf", &r, &R, &H, &v);double low = 0, high = H;double mid;while (low + 0.0000001 < high){mid = (low + high) / 2;double temp = mid*(R - r);if ((temp*(temp + 3 * H*r) + H*H*r*r * 3)*mid*acos(-1.0)>3 * v*H*H)
high = mid;else low = mid;}printf("%.6lf\n", mid);}return 0;}

2 0