刚刚接触二分法时候,是在写cup题的时候,求水的高度,
一个杯子装了很多水,可以把杯子看成圆台,并给出圆台的底面半径,顶部半径,高还有水的体积,求水的高度。
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位小数
在这道题中,我们算出高的一个大致范围,mid和max令高在mid设max之间,先是高h=(mid+max)/2,进去计算,看误差是否符合条件,如果符合条件的话,就成立,不符合的话,在其左右区间依次取半,令mid或者max=高,在对高进行重新赋值,循环如此,知道用此高h所算出来的体积与题目所给的体积相等的误差在题目范围的时候即可。
这是C语言版本的
#include <stdio.h>
#include <math.h>
#define PI 3.14159265
double check(double h,double r,double R,double H,double V)
{
double u;
u=h/H*(R-r)+r;
return PI/3*(r*r+r*u+u*u)*h;//利用假定的h对水的体积进行求解
}
void main()
{
int t;
double r,R,H,V,mid,vv,f,l;
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf",&r,&R,&H,&V);
f=0;
l=H;
while(l-f>1e-10)
{
mid=(l+f)/2;
vv=check(mid,r,R,H,V);
if(fabs(vv-V)<=1e-10)//当我们用假定的高h所求出的水的体积vv与水真实的体积V相差小于1e-10时,成功
break;
else if(vv>V)
l=mid;//或者l=mid-1e-10
else
f=mid;//或者f=mid+le-10
}
printf("%.6lf\n",mid);//当vv与V的误差小于1e-10时,则表示mid求解成功
}
}
这是c++版本的
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
using namespace std;
#define PI 3.141592653589793
#define exp 1e-9
double solve(double r,double R,double h,double H)
{
double u = h/H*(R-r) + r;
return PI/3*(r*r+r*u+u*u)*h;
}
int main()
{
int t;
double r,R,H,V,mid,vv,f,l;
scanf("%d",&t);
while(t--)
{
scanf("%lf%lf%lf%lf",&r,&R,&H,&V);
f=0;
l=100;
while(l-f>exp)
{
mid=(l+f)/2;
vv=solve(r,R,mid,H);
if(fabs(vv-V)<=exp)
break;
else if(vv>V)
l=mid-exp;
else
f=mid+exp;
}
printf("%.6lf\n",mid);
}
return 0;
}
C语言版本与c++版本都是AC码。