二分查找(一部分)

本文通过二分法解决了一道数学问题:利用两个不同长度的梯子交叉点的高度来计算街道的宽度。介绍了算法的基本思路及核心代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Crossed Ladders
Input: 
Standard Input

Output: Standard Output

Time Limit: 1 Second

 

A narrow street is lined with tall buildings. An x foot long ladder is rested at the base of the building on the right side of the street and leans on the building on the left side. A y foot long ladder is rested at the base of the building on the left side of the street and leans on the building on the right side. The point where the two ladders cross is exactly c feet from the ground. How wide is the street?

Each line of input contains three positive floating point numbers giving the values of xy, and c.

For each line of input, output one line with a floating point number giving the width of the street in feet, with three decimal digits in the fraction.

Sample Input                             Output for Sample Input

30 40 10 
12.619429 8.163332 3 
10 10 3 
10 10 1 
                      
26.033 
7.000 
8.000 
9.798 


  这道题用的是二分法,关于二分我掌握的可以说是不怎么好,也可以说是一清二白。现在我说一下我二分的心得,二分有二分查找,好像都是二分查找吧,

这种解不出根的方程,二分是再好不过了,只是我对其理解不深,没有做出来,下面上代码,(时间复杂度logn)时间复杂度很重要!!!!

  1. #include<cstdio>  
  2. #include<cmath>  
  3. #include<algorithm>  
  4. #define Min(a,b) a <= b ? a : b;  
  5. using namespace std;  
  6.   
  7. double x, y, c;  
  8.   
  9. double get_ans(double w)  
  10. {  
  11.     return 1 - c / sqrt(x * x - w * w) - c / sqrt(y * y - w * w);  
  12. }  
  13.   
  14. int main()  
  15. {  
  16.     while(~scanf("%lf%lf%lf",&x,&y,&c))  
  17.     {  
  18.         double l = 0, mid, r = Min(x,y);  
  19.         while(r - l > 1e-8)  
  20.         {  
  21.             mid = (l + r) / 2;  
  22.             if(get_ans(mid) > 0)  
  23.                 l = mid;  
  24.             else  
  25.                 r = mid;  
  26.         }  
  27.         printf("%.3lf\n",mid);  
  28.     }  
  29.     return 0;  
  30. }  

核心部分:

  1.  while(r - l > 1e-8)  
  2.         {  
  3.             mid = (l + r) / 2;  
  4.             if(get_ans(mid) > 0)  
  5.                 l = mid;  
  6.             else  
  7.                 r = mid;  
  8.         }  
另外这个题还要看函数的单调性,单调增还是单调减对以后的判断至关重要,这个函数是单调增的,就是随着自变量的增大而增大,所以,当其大于零的时候,说明还有点小,得变大,所以改变左区间,小于零的时候也同理判断,直到左右相等或最接近,就可以输出结果了,

现在想想,这个方法也是太精辟了,还是我没有深刻理解其内涵,,,,,加油了要。(还要说一点,二分查找之前是要排一下序的,当然,这个题目没有事先给的序列,就不用排序了)

其实,还有一个问题,就是二分排序的精度问题(感觉有1e-6和1e-8两种,其实我也分辨不清楚,其实感觉这个精度问题也不是特别要紧,就是尽量让它趋近于一个小数),关于二分,我知道的还是很少的,以后还要不断总结,二分排序啦

这里有一个链接http://blog.youkuaiyun.com/caobo1212/article/details/7905974关于二分的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值