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. 无空数据
每组数据包含一行,并且有四个数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
1.刚看完其实完全没有想到二分,最后看到了可以保留6位小数,才想到二分半径。但是又因为高度是不确定的,所以要用数学三角形相似的方法得出h和r的关系
height=(H*(mid-r)/(R-r)),二分的时候判断条件就利用体积大小比较即可
#include<iostream>
#include"math.h"
#include<cstdio>
#define pi acos(-1)
const double EPS=1e-9;
using namespace std;
double R,r,H,V;
double Height(double mid)
{
//return 3*v/(a*a+b*b+a*b)/pi;
double height=0;
height=(H*(mid-r)/(R-r));
return height;
}
double Volume(double mid)
{
double h=Height(mid);
return (pi*h*(R*R+mid*mid+R*mid)/3);
}
double binary()
{
double low=r,high=R;
double mid=0;
do
{
mid=(high-low)/2+low;
// cout<<"1"<<endl;
if(Volume(mid)>V) high=mid;
else low=mid;
}while(fabs(Volume(mid)-V)>EPS);//broken,·¢ÉúÒç³ö£»
double ans=Height(mid);
return ans;
}
int main()
{
int T;
cin>>T;
while(T--)
{
cin>>R>>r>>H>>V;
// cout<<Height(2.0)<<" "<<Volume(2.0)<<endl;
double ans = binary();
printf("%.6lf\n",ans);
}
return 0;
}