Expanding Rods(POJ--1905【二分查找】

Description

When a thin rod of length L is heated n degrees, it expands to a new length L'=(1+n*C)*L, where C is the coefficient of heat expansion. 
When a thin rod is mounted on two solid walls and then heated, it expands and takes the shape of a circular segment, the original rod being the chord of the segment. 

Your task is to compute the distance by which the center of the rod is displaced. 

Input

The input contains multiple lines. Each line of input contains three non-negative numbers: the initial lenth of the rod in millimeters, the temperature change in degrees and the coefficient of heat expansion of the material. Input data guarantee that no rod expands by more than one half of its original length. The last line of input contains three negative numbers and it should not be processed.

Output

For each line of input, output one line with the displacement of the center of the rod in millimeters with 3 digits of precision. 
题意:两个墙之间夹了一根细杆,这个细杆经过加温可以变长且往正上方拱(如图所示),加温后的长度与原先的长度符合一个函数关系式L'=(1+n*C)*L,求变形后杆的中点距离变形前杆的中点为多少。
思路:用二分不断枚举答案,满足要求即是答案。二分的下限是0,上限是L/2。
知识点:  勾股定理:r^2+(L/2)^2=(r-h)^2
                  反三角函数:A=arcsin(L/2/r)
                  弧长公式:l=r*A
注意:  1.对于浮点数来说,不能直接比较大小,因为如果直接比较在比较过程中可能会有精度上的损失。
              2.输出对于G++来说一定要用“%f”
                 输出对于G++来说一定要用“%f”
                 输出对于G++来说一定要用“%f”
                【重要的事要说3遍!!!】

Sample Input

1000 100 0.0001
15000 10 0.00006
10 0 0.001
-1 -1 -1

Sample Output

61.329
225.020
0.000

#include <cstdio>
#include <algorithm>
#include <cmath>
#define INF 0x3f3f3f3f
#define esp 1e-8         //对于精度要因题而异,如果精度不够小可能会WA,如果精度过小可能会TL
using namespace std;
int dmp(double x)       //对于浮点数的比较
{
       return fabs(x)<esp?0:(x>0?1:-1);
}
int main()
{
    //freopen("lalala.text","r",stdin);
    double L,n,C;
    while(~scanf("%lf %lf %lf",&L,&n,&C))
    {
          if(L<0&&n<0&&C<0)
          break;
         double ll=(1+n*C)*L;       //弧长
         double l=0,r=L/2,mid;
         while(dmp(r-l)>0)
         {
            mid=(l+r)/2;
            double rr=(L*L+4*mid*mid)/(8*mid);
            double lll=2*rr*asin(L/(2*rr));       //枚举得来的弧长
            if(dmp(lll-ll)>0)
            r=mid;                 //对于浮点数来说左右区间是不能再移动了,因为你不知道该移动多少,如果同整数一样加1的话,那么中间的小数就枚举不到,中间的小数可能就包含答案,所以对于浮点数来说,左右区间直接取中间值即可
            else
            l=mid;                //同上
         }
         printf("%.3f\n",l);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值