POJ2507 Crossed ladders
本题复习实数域上的二分。
实数域上的二分与普通的二分不同,它需要设置一个精度,据题目而定(一般不会小于1e-9)。
本题首先推公式,由相似三角形其实可以解得距离的关于x,y,c的表达式,但是我们发现太烦了,而且解出来也是带高次项的,题意肯定不是想让你解。
于是我们可以发现本题可以用二分求函数零点。
但是用二分求函数零点有条件:函数必须是单调且连续的(见高中数学零点存在性定理)。
所以此题如果严谨一点需要证明单调性。
如果数学计算能力不是太强,打表一波也是很快的。
当我们发现单调后就可以大胆用二分了。
几个实数域题目易错的问题:
- 一定要注意l,r,mid都是double
- 输出是注意精度
- 有些题目注意分析精度损耗(尽量少用平方根等)
另外,在有些网站提交时发现Output Limit Exceeded是因为系统一直在等待你输入,输入没有结束。
例如:while (scanf("%lf%lf%lf",&x,&y,&c))
就是Output Limit Exceeded
改为:while (scanf("%lf%lf%lf",&x,&y,&c)==3)
即可
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
double x,y,c,mid,l,r;
double f(double m){
return (1/sqrt(x*x-m*m)+1/sqrt(y*y-m*m)-1/c);
}
int main()
{
while (scanf("%lf%lf%lf",&x,&y,&c)==3){
mid=0;
l=0;
r=min(x,y);
while (r-l>=1e-9){
mid=(l+r)/2.0;
if (f(mid)>0){
r=mid;
}
if (f(mid)<0){
l=mid;
}
}
printf("%0.3f\n",mid);
}
return 0;
}