标签: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 }
标签:while 过程 scanf 一半 include cst 链接 org 二分
原文地址:http://www.cnblogs.com/Blogggggg/p/7497006.html