浮点数的二分
例题:题目描述
告诉你圆台的高h,下地面半径R,和上底面半径r;你需要平行于地面切割圆台,使切割后的圆台上下两部分相等,输出切割平面的高度H(切割平面与“上”底面的距离)
输入
第一行一个t表示t组数据,每组数据三个整数h,R,r(t<=10;1<=r,R,h<=100)
输出
如题所述输出一个浮点数H(保留3位小数)
样例输入
2
7 17 9
12 13 10
样例输出
4.489
6.770
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <algorithm>
#define EPS 1e-8
using namespace std;
double cal(double mid,double R2,int r){
double v2;
v2=acos(-1.0)*mid*(R2*R2+r*r+R2*r)/3;
//printf("%d\n",v2)
return v2;
}
int main ()
{
//freopen("D:\\input.txt", "r", stdin);
//freopen("D:\\output.txt", "w", stdout);
int t,h,R,r;
double H;
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&h,&R,&r);
double v=acos(-1.0)*h*(R*R+r*r+R*r)/6;
double lb=h*1.0;
double rb=0.0;
double R2;
for( int i = 0; i < 100; ++ i )
{
double m =(lb + rb) / 2;
R2=(R-r)*m/h+r;
if(cal(m,R2,r)>=v) lb=m;
else
rb=m;
}
H=lb;//二分
//printf("%lf\n",R2);
//printf("%lf\n",v1);
printf("%.3lf\n",H);
}
return 0;
}
另一种
for( int i = 0; i < 100; ++ i )
{
double m =(lb + rb) / 2;
R2=(R-r)*m/h+r;
if(cal(m,R2,r)>=v) lb=m;
else
rb=m;
}
H=lb;
最后时 lb=rb