LOJ #10016 灯泡

题面

相比 wildleopard 的家,他的弟弟 mildleopard 比较穷。他的房子是狭窄的而且在他的房间里面仅有一个灯泡。每天晚上,他徘徊在自己狭小的房子里,思考如何赚更多的钱。有一天,他发现他的影子的长度随着他在灯泡和墙壁之间走到时发生着变化。一个突然的想法出现在脑海里,他想知道他的影子的最大长度。
这里写图片描述

思路

首先,分治肯定是能够想到的,但是是二分还是三分呢,我们只需要思考一下就能知道,我们设地上影长为L1,墙上为L2,人走近时L1增加,L2减小,走远时L1减小,L2增加——这是个二次函数,所以一定使用三分法。
然后让我们来算L的长度,首先L1=D-X(X为人到左墙距离),L2=H-(H-h)*D/X(相似三角形)。
如果不理解可看下图
这里写图片描述
两个蓝的三角形为相似三角形,对应边的比值相同。
然后三分一下x的范围即可。

代码

(我都讲得这么详细了还需要代码?)

#include<bits/stdc++.h>
using namespace std;
double H,h,D,mid1,mid2;
int t; 
double check(double x)
{
    return D-x+H-(H-h)*D/x;
}
int main()
{
    cin>>t;
    while (t--)
    {
        cin>>H>>h>>D;
        double l=(H-h)*D/H,r=D;//注意l要从(H-h)*D/H开始,不然墙上没有影子。
        while (l+1e-10<=r)
        {
            mid1=(l+r)/2;
            mid2=(mid1+r)/2;
            if (check(mid1)>=check(mid2)) r=mid2;else l=mid1;  
        }
        printf("%.3lf\n",check(mid1));
    }
    return 0;
 } 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值