poj1905 Expanding Rods

来源:互联网 发布:淘宝买手机不给我发票 编辑:程序博客网 时间:2024/05/01 23:17

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. 
Sample Input
1000 100 0.000115000 10 0.0000610 0 0.001-1 -1 -1
Sample Output
61.329225.0200.000

题意:

有一个杆子,夹在两堵墙的中间,如果温度升高,那么它就会弯曲成一个圆状的杆,给出变化的温度,求细杆中点变化了多少

输入
  
包含多组数据(每组占一行)。每一行包含三个非负数:细棍的长度L,温度的变化值N和细棍材料的热膨胀系数C。输入数据保证细棍不会膨胀超过自己的一半。
输入数据以三个连续的-1结尾。
  
输出
  
对于每一组数据,输出计算的距离,答案保留三位小数。

题意解释得不清楚,随便看看


题解:

这是一道分治题,或者说二分题,我们的二分对象就是细杆中点变化的值,设其为h

二分的上下界是多大呢,令Len=(1+n*C)*L

下界为0,上界为sqrt(Len*Len-L*L),这是比较显然的

有了这个条件h,我们就可以把现在细杆所在圆弧的圆表示出来了

作几根辅助线,画一下图,可以发现能够用勾股定理将R表示出来

R*R=(R-h)*(R-h)+(L/2)*(L/2)

二次项可以约去,于是R=L*L/(8*h)+h/2;

然后可以用反三角函数将现在的圆弧长度给表示出来

l=2*asin(L/2/R)*R,那么通过比较l和Len,就可以确定是往上二分还是往下二分了

若是l>Len,那么往下,否则往上

#include<iostream>#include<cstdio>#include<algorithm>#include<cmath>const double esp=0.000001;using namespace std;double L,N,C,Len,L1,l,r,mid,R;int main(){    while(1)    {        scanf("%lf%lf%lf",&L,&N,&C);        if(L==-1&&N==-1&&C==-1) return 0;        Len=(1+N*C)*L; l=0.0; mid=0.0;        r=sqrt(Len*Len/4-L*L/4);        while(r-l>=esp)        {            mid=(r+l)*0.5;            R=L*L/(8*mid)+mid/2;            if(2*asin(L/2/R)*R<Len) l=mid;            else r=mid;        }        printf("%.3lf\n",mid);    }}


原创粉丝点击