链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1609
题意:如图,给出弧长和弦长,求“?”处的距离h。
思路:这里是二分半径r,要注意好精度,要不wa到死啊。特别要注意先判断一下n*c,如果结果太小则不能构成一个圆,就直接输出0好了。
但是如果是二分h的话,精度就好控制很多。由于题目说细棒最多伸长为3L/2,所以h的范围是(0,L/2), r=(4*h*h+L*L)/(8*h).
二分半径:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const double inf=0xffffffff; const double eps=1e-8; const int maxn=100; double l1,l2; double F(double r) { return 2*r*asin(l1/(2*r))-l2; } double binary() { double l=0.5*l1,r=inf,m; while(l+eps<r)//for(int i=0;i<150;i++)// { m=l+(r-l)/2; if(F(m)>eps) l=m; else r=m; } return m; } int main() { // freopen("in.cpp","r",stdin); double n,c,r; while(scanf("%lf%lf%lf",&l1,&n,&c)) { if(l1<0 && n<0 && c<0) break; if(n*c<eps) { printf("0.000\n"); continue; } l2=(1+n*c)*l1; r=binary(); double d=sqrt(r*r-l1*l1/4); printf("%.3lf\n",r-d); } return 0; }
二分高度h:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> using namespace std; const double inf=0xffffffff; const double eps=1e-8; const int maxn=100; double l1,l2; double F(double r) { return 2*r*asin(l1/(2*r))-l2; } double binary() { double left=0,right=l1/2,m; while(left+eps<right)//for(int i=0;i<150;i++)// { m=left+(right-left)/2; double r=(4*m*m+l1*l1)/(8*m); if(F(r)>eps) right=m; else left=m; } return m; } int main() { // freopen("in.cpp","r",stdin); double n,c,r; while(scanf("%lf%lf%lf",&l1,&n,&c)) { if(l1<0 && n<0 && c<0) break; l2=(1+n*c)*l1; double h=binary(); printf("%.3lf\n",h); } return 0; }
究竟是我抛弃了历史,还是历史遗弃了我。