zoj 3203 - Light Bulb (三分)

三分第一题,,,,

题意:

某人在房间内左右走动,要求这个人的影子最大长度是多少。

思路:

明显的,人在灯下的影子长度是0,这时他如果向前走的话,影子会逐渐变长,到影子投到墙上的时候,由于情况复杂,就不考虑如果变化的了,反正到最后人走到墙的位置的时候,影长度便是人的身高了,所以影长的变化曲线要么是单调递增的【如第一组样例】要么是向上凸的【如第二、三组样例】,所以三分的方法还是比较适合的。。。

由于影长从灯下0一直到恰好没投影到墙上的过程是一个单调的过程,我们可以把这段忽略,直接求解,投影到墙上后,影长的变化即可。

代码如下:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <map>
#include <algorithm>

#define LL long long
#define LLU unsigned long long
#define INF 0x7fffffff
#define eps 1e-7

using namespace std;

double calcu(double H, double h, double D, double x)
{
    double t = (h*D-H*x)/(H-h);
    return H*t/(D+t)+x;
}
int main ()
{
    int t;
    double H, h, D;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lf%lf%lf",&H, &h, &D);
        double l = 0, r = D*h/H;
        double mid, midmid, t1, t2;
        while(r-l>eps)
        {
            mid = (l+r)/2, midmid = (mid+r)/2;
            t1 = calcu(H,h,D,mid);
            t2 = calcu(H,h,D,midmid);
            if(t1>t2) r = midmid;
            else l = mid;
        }
        printf("%.3lf\n",calcu(H,h,D,l));
    }
    return 0;
}


posted on 2013-08-05 16:55  Primo...  阅读(146)  评论(0)    收藏  举报