ZOJ-3203 Light Bulb

Light Bulb


Time Limit: 1 Second      Memory Limit: 32768 KB


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 Hh 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

题目大意:给你一个灯泡的高度H,一个人的高度h,地面的长度D现在问你影子在光的照射下,最长有多长

题目就是这样很简单,然后有两种做法,

第一种;公式法,今天大脑比较乱,化了半天才化简出来

三种情形:

 1:影子能落在地上,很容易就知道,,当灯和人和墙角三点共线的时候影子最长,而且H D和墙角形成的三角形与和h墙角,影子的长度形成的三角形相似此时影子长度为h/H*D(相似三角形)
 2:人靠墙,此时影子长度即为人的身高h
 3:影子既有落在地上的也有在墙上的此时 设人距离灯的距离为x(则地上的影子长为D-x,相似三角形有:y/(D-x)=(H-h)/x
 y=(D-x)(H-h)/x;影子长为h-y+D-x; 

即为:D-x+H-(H-h)*D/x-->D+H-(x+(H-h)*D/x)不等式定理:得到最大值:D+H-2*sqrt((H-h)*D)

即如下图:

然后判断下它的满足条件即可:

代码:

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1e-8
#define ll long long
#define inf 0x3f3f3f3f
#define bug printf("mmp\n");
#define ul unsigned long long
#define mm(a,b) memset(a,b,sizeof(a))
#define T()int test,q=1,tt;scanf("%d",&test),tt=test;while(test--)
const int N=1e2+10;
const int maxn=1e6+100;
const int mod=1000000007;
int main()
{
    T()
    {
        double H,h,D;
        cin>>H>>h>>D;
        double ans1=sqrt((H-h)*D);
        double ans2=(H-h)*D/H;
        if(ans1>=D)///情况2
            printf("%.3lf\n",h);
        else if(ans1<ans2)///情形1
            printf("%.3lf\n",D*h/H);
        else
            printf("%.3lf\n",D+H-2.0*ans1);
    }
    return 0;
}

第二种做法:

三分:直接上代码:

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<string>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define eps 1e-8
#define ll long long
#define inf 0x3f3f3f3f
#define bug printf("mmp\n");
#define ul unsigned long long
#define mm(a,b) memset(a,b,sizeof(a))
#define T()int test,q=1,tt;scanf("%d",&test),tt=test;while(test--)
const int N=1e2+10;
const int maxn=1e6+100;
const int mod=1000000007;
double H,h,D;
double finds(double x)
{
    return D-x+H-(H-h)*D/x;
}
double three_search(double low ,double high)
{
    double mid=0,mids=0;
    while(high-low>=eps)
    {
        mid=(low+high)*0.5;
        mids=(mid+high)*0.5;
        if(finds(mid)>=finds(mids))
            high=mids;
        else
            low=mid;

    }
    return finds(high);
}
int main()
{
    T()
    {
        cin>>H>>h>>D;
        printf("%.3lf\n",three_search(D-h*D/H,D));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/lee371042/article/details/86531184