【二分查找】[Openjudge noi 1.11 09]膨胀的木棍

题目描述:
当长度为L的一根细木棍的温度升高n度,它会膨胀到新的长度=(1+n×C)×L,其中C是热膨胀系数。
当一根细木棍被嵌在两堵墙之间被加热,它将膨胀形成弓形的弧,而这个弓形的弦恰好是未加热前木棍的原始位置。
你的任务是计算木棍中心的偏移距离。
这里写图片描述

题目分析:
首先可以发现我们需要二分的内容是当前角度,那么角度的范围可以很容易发现,因为木管长度不超过1.5倍那么就定角度为0-π因为如果圆心角过小会发现半径十分的大根本存不下,其实这种情况的时候木棍长度的变化也是十分的小的那么
if(Temp * ks * Len1 <= eps)
判断一下如果满足那么直接就输出0.000,
其他的情况我们可以发现如果我们枚举的是12的圆心角那么很方便处理(这里的r是半径)这里圆心角用2a表示r=L12sin(a)那么圆弧就等于L12sin(a)×2×π×2a2×π=L1×asin(a)很容易可以发现在弦长相同的时候圆心角越大弧长越大,那么反过来如果我的当前角度的弧长大于了要找的弧长,那么就减小圆心角,直到找到为止,然后剩下的就是算出半径然后减去圆心到弧的距离就行了。

#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std;
const double PI = asin(1.0);
const double eps = 1e-14;
int main(){
    double Len1, Len2, Temp, ks;
    while(scanf("%lf%lf%lf", &Len1, &Temp, &ks) != EOF){
        Len2 = (1.0 + Temp * ks) * Len1;
        double l=0, r=PI;
        if(Temp * ks * Len1 <= eps){
            printf("%.3lf\n", 0.0);
            continue;
        }
        while(l < r - eps){
            double mid = (l + r)/2.0;
            if(Len1/sin(mid)*PI*(mid/PI) >= Len2)
                r = mid;
            else l = mid;
        }
        printf("%.3lf\n", Len1/2/sin(l)-Len1/2/sin(l)*cos(l));
    }

    return 0;
}

posted on 2015-11-06 19:43  JeremyGuo  阅读(528)  评论(0编辑  收藏  举报

导航