poj 1905 Expanding Rods 二分答案
题目地址: http://poj.org/problem?id=1905
思路:
列出方程 2*R*x=L‘
2*R*sin(x)=L
两式相除即得 x/sin(x) = 1+n*c 前提x!=0 就是 n*c>0
答案就是 L/2* (1/sin(x)-1/tan(x)) 三角函数化简为 L/2*tan(x/2) x 在0~ PI/2 于是关于x是单增的, 反函数也是单增的,x/sin(x) 也是单增的
一开始的思路是先用 二分把 x/sin(x) = 1+n*c 里面的x解出来,然后带进 L/2*tan(x/2) 计算 虽然样例过了,但是还是wa,看来是精度问题。
所以直接二分答案,ans= L/2*tan(x/2) => x=2*arctan(ans*2/L) 这个关于ans是单增的,带进 x/sin(x) 也是单增的 可以二分了
代码:
#include<iostream> #include<cmath> #include<cstdio> const long double PI=acos(-1.0); long double L,n,c; long double f(long double x) { double xx=2*atan(2*x/L); return xx/sin(xx); } using namespace std; int main() { long double l,r,mid; while(cin>>L>>n>>c) { if(L==-1) break; l=0; //r=PI/2; r=L; double ans; if(n*c>0) { while(r-l>1e-4) { mid=(l+r)/2; if(f(mid)>1+n*c) r=mid; else l=mid; } //ans=1.0/sin(l)-1.0/tan(l); ans=l; } else ans=0; printf("%.3lf\n",ans); } }