思路:二分
分析:
1 题目要求的是找到变形后的弧和原来的弦中心的距离ans
2 很明显的数学题,题目明确告诉我们变形后的增加弧长不会大于L/2,那么我们就可以确定ans的范围[0,L/2),那么我们就可以对ans进行二分,然后利用三角形的勾股定理求出半径r,求出了半径我们可以求出圆心角,然后进一步求出弧长,最后和newLen(最终变形后的长度)进行比较;
3 很明显这一题的精度要求很高。如果我们还是利用while(left - right < eps){} 这样肯定是不行的,当left无限接近去right的时候将陷入无限循环或者是得到不够准确的答案,所以这里我们改成while(right-left > eps){}这样我们就可以得到准确的答案;还有在确定left 和 right的时候不再是left = mid+1,而是利用left = mid,然后不断的逼近求出最后的ans即为left。
4 注意数据就是三个数里面只要有一个为0,那么ans肯定是0,不用进行二分。
代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; #define eps 1e-8 int n; double len , c , newLen; void solve(){ double left , right , mid , tmp , ans; newLen = (1+n*c)*len;/*最终变形后的长度*/ tmp = (len/2)*(len/2); left = 0 , right = len/2;/*二分的上下界*/ while(right - left > eps){ mid = (right+left)/2; double r = (mid*mid+tmp)/(2*mid);/*求出半径*/ double tmpLen = asin((len/2)/r)*2*r;/*求出弧长*/ if((tmpLen-newLen) > eps) right = mid; else left = mid; } printf("%0.3lf\n" , left); } int main(){ while(scanf("%lf%d%lf" , &len , &n , &c)){ if(len < 0 && n < 0 && c < 0) break; if(len == 0 || n == 0 || c == 0)/*特殊处理*/ printf("0.000\n"); else solve(); } return 0; }
时间: 2024-10-29 09:45:15