链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1609
题解
经过各种推导以及瞎搞,也算是得到了一个AC
设圆心坐标为
(
−
a
,
0
)
(-a,0)
(−a,0)
可以列出方程
L
′
2
=
a
2
+
L
2
4
×
a
r
c
t
a
n
(
a
2
L
)
\frac{L'}{2}=\sqrt {a^2+\frac{L^2}{4}} \times arctan( \frac{a}{2L} )
2L′=a2+4L2×arctan(2La)
令
f
(
a
)
=
a
2
+
L
2
4
×
a
r
c
t
a
n
(
a
2
L
)
f(a)=\sqrt {a^2+\frac{L^2}{4}} \times arctan( \frac{a}{2L} )
f(a)=a2+4L2×arctan(2La)
求导,并令
f
′
(
a
)
=
0
f'(a)=0
f′(a)=0,得到一个方程
1
=
1
a
a
r
c
t
a
n
(
L
2
a
)
1=\frac{1}{a} arctan( \frac{L}{2a} )
1=a1arctan(2aL),右边单调,所以这个方程要么只有一个解,要么没有解
求极限发现
f
′
(
0
+
)
=
0
f'(0^+)=0
f′(0+)=0,
f
(
+
∞
)
=
+
∞
f(+\infty)=+\infty
f(+∞)=+∞,结合零点个数,得到导函数横不小于
0
0
0
那
f
(
a
)
f(a)
f(a)就单调不减
所以我可以二分求解
注意当
L
′
=
L
L'=L
L′=L时,原方程只有当
a
→
+
∞
a\rightarrow +\infty
a→+∞时才成立,解不出实数解,需要特判
代码
//数学推导、二分
#include <bits/stdc++.h>
#define eps 1e-8
using namespace std;
double L, n, C, L2;
int main()
{
double l, r, a, ans;
while(scanf("%lf%lf%lf",&L,&n,&C), L>-eps)
{
L2=(1+n*C)*L;
if(fabs(n*C)<eps)
{
printf("0.000\n");
continue;
}
l=0, r=1e10, a=(l+r)/2;
for(int i=1;i<=100;i++)
{
if(sqrt(a*a+L*L/4)*atan(L/(2*a))<L2/2)r=a;
else l=a;
a=(l+r)/2;
}
ans=sqrt(a*a+L*L/4)-a;
printf("%.3lf\n",fabs(ans)<0.0005?0.0:ans);
}
return 0;
}