Light Bulb(三分)

Light Bulb

Compared to wildleopard’s wealthiness, his brother mildleopard is rather poor. His house is narrow and he has only one light bulb in his house. Every night, he is wandering in his incommodious house, thinking of how to earn more money. One day, he found that the length of his shadow was changing from time to time while walking between the light bulb and the wall of his house. A sudden thought ran through his mind and he wanted to know the maximum length of his shadow.
在这里插入图片描述

Input

The first line of the input contains an integer T (T <= 100), indicating the number of cases.

Each test case contains three real numbers H, h and D in one line. H is the height of the light bulb while h is the height of mildleopard. D is distance between the light bulb and the wall. All numbers are in range from 10-2 to 103, both inclusive, and H - h >= 10-2.

Output

For each test case, output the maximum length of mildleopard’s shadow in one line, accurate up to three decimal places…

Sample Input

3
2 1 0.5
2 0.5 3
4 3 4

Sample Output

1.000
0.750
4.000

思路:
题目上说,人左右走动,要求影子L的最长长度。看图很容易就可以发现当灯,人的头部和墙角成一条直线时,此时的长度是影子全在地上的最长长度。然后就可以发现构成了相似三角形。根据图上所示可以得到函数
f(x) = D - x + H - D * (H-h) / x ;
这个函数是一个先增后减的一个凸函数,所以用三分的方法。
完整代码:

#include<iostream>
#include<cstdio>
using namespace std;
double H,h,D;
const double eps=1e-5;
double f(double x)          //相似三角形
{
    return D-x+H-D*(H-h)/x;
}
double thrp(double l,double r) //三分
{
    double m1,m2;
    while(r-l>=eps)
    {
        m1=(l+r)/2;
        m2=(m1+r)/2;
        if(f(m2)-f(m1)>=eps)
        {
            l=m1;
        }
        else
        {
            r=m2;
        }
    }
    return f(m1);
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        cin>>H>>h>>D;
        double l=(H-h)*D/H;         //区间左端点
        double r=D;                 //右端点
        printf("%.3lf\n",thrp(l,r));
    }
    return 0;
}
发布了60 篇原创文章 · 获赞 69 · 访问量 2818

猜你喜欢

转载自blog.csdn.net/qq_45856289/article/details/104590318