zoj 3203 - Light Bulb (三分)

本文介绍了一种计算人在房间内走动时其影子最大长度的问题,并使用三分法来寻找最优解。通过数学公式推导,给出了具体的C++实现代码。

三分第一题,,,,

题意:

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

思路:

明显的,人在灯下的影子长度是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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值