POJ 1905 Expanding Rods(几何+二分)

558 篇文章 0 订阅
273 篇文章 0 订阅

POJ 1905 Expanding Rods(几何+二分)

http://poj.org/problem?id=1905

题意:

       一根两端固定在两面墙上的杆 受热弯曲后变弯曲

求前后两个状态的杆的中点位置的距离. 弯曲后的杆可以看成一个圆的弧,而弯曲前的杆可以看成是该弧的弦.

分析:

      

假设当前的圆半径为r,且该弧S对应的圆心角为2 θ. h是我们要求的距离.那么我们可以推过上图得到下面3个方程:

       (1)θr = 1/2*s  (弧/圆周长==弧圆心角/2π)

(2)sinθ= 1/2*L/r (正弦定理)

(3)勾股定理  r^2 – ( r – h)^2 = (1/2*L)^2

       那么化简上述公式可得:

      

那么我们可以通过二分h的长度(h的范围是[0,0.5L],该范围值也不好证明)来计算r的值,然后通过第二个等式来验证r的值是否正确. 如果当前通过h的值算出的r值使得等式(2)右边小于s,那么h值应该更大. 否则L值应该更小.

注意: 二分有个很重要的前提就是单调,本题需要证明等式(2)右边是关于r单调递增的且要证明hr也是成正比的关系.

下面这个大神把上面的单调关系证明了,还带图解:

http://blog.csdn.net/zhengnanlee/article/details/18494917

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const double eps=1e-5;

double L,C,n,S;

double get_s(double h)
{
    double r= (4*h*h+L*L)/(8*h);
    return 2*r*asin(L/(2*r));
}

int main()
{
    while(scanf("%lf%lf%lf",&L,&n,&C)==3)
    {
        if(L<0 && n<0 && C<0) break;
        S=(1+n*C)*L;
        double low=0,high=L/2;
        while(high-low>eps)
        {
            double mid=(low+high)/2;
            if(S>get_s(mid)) low=mid;
            else high=mid;
        }
        printf("%.3lf\n",high);
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值