码迷,mamicode.com
首页 > 其他好文 > 详细

POJ1905

时间:2017-09-09 09:41:32      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:while   过程   scanf   一半   include   cst   链接   org   二分   

题目链接:http://poj.org/problem?id=1905

题目大意:

  竹竿受热会膨胀。设其原长为 L ,受热膨胀后的长度 L‘=(1+n*C)*L ,其中 n, C, L都是要输入的参数。

  原本竹竿刚好撑在两面墙中间,受热之后长度变长,于是会弯出一道弧线,求弧线最高点对于水平面的高度 h。

解题思路:

  先求出实际弧长(也就是受热膨胀后的竹竿长度),然后二分各种 h,求出 h 对应的弧长,如果弧长小于实际弧长,那么证明该 h 偏小,否则 h 偏大。具体还有几个细节请看代码。

AC代码:

 1 #include <cstdio>
 2 #include <cmath>
 3 using namespace std;
 4 const double PI=acos(-1.0);
 5 int main(){
 6     double L,n,C;
 7     while(scanf("%lf%lf%lf",&L,&n,&C)==3&&(L>=0&&n>=0&&C>=0)){
 8         double nL=(1.0+n*C)*L;  //nL--实际弧长
 9         double l=0.0,r=0.5*L;
10         while(r-l>1e-8){
11             double mid=(l+r)/2;
12             double Rs=L*L/(8.0*mid)+mid/2;  //Rs--mid对应的弧的半径
13             double thata=asin(L/(2*Rs));    //弧角的一半。这里其实还有一种求法:acos((Rs-mid)/Rs),但如果用这种求法可能就WA了,想来可能是Rs这个有误差的值在此出现了2次(另一种求法之出现了1次),被卡精度了。以后做计算几何的时候要注意这个问题:在运算过程中尽量少用存在精度问题的数据!
14             double LL=Rs*2.0*thata;     //弧长公式
15             if(LL<nL)   l=mid;
16             else    r=mid;
17         }
18         printf("%.3f\n",(l+r)/2);   //这里有个巨坑!要是写"%.3lf\n"就WA,屡试不爽!无解。
19     }
20     return 0;
21 }

 

POJ1905

标签:while   过程   scanf   一半   include   cst   链接   org   二分   

原文地址:http://www.cnblogs.com/Blogggggg/p/7497006.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!