灯泡
三分人所站位置求地面影长加墙上影高
正文
// 原题:https://oj.yecheng.tv/p/T1438
// 题意:灯高 H、人高 h、灯到墙距离 D,人从灯底走向墙,求「地面影长 + 墙上投影高度」总长的最大值,保留 3 位小数。
// 思路:三分法求单峰函数的最大值。
// 1. 设人离灯的水平距离为 x,灯的光线经头顶后打在 x = D 处的高度 y = H + (h - H) * D / x。
// 2. y > 0 时光打在墙上,总长 = (D - x) + y;否则光提前落地,总长 = x * h / (H - h)。
// 3. 总长关于 x 是先增后减的单峰函数,三分即可。
// 复杂度:O(log(1/eps)) 时间 / O(1) 空间
// 易错点:x = 0 时公式除零,三分从区间内部取点不会取到 0,但仍要保证 H > h 时 (H - h) 不为 0。
// 易错点:影子长度的公式要分「打到墙上」和「打到地面」两种情况,混用会导致三分结果偏大。
#include <bits/stdc++.h>
using namespace std;
int main(){
double H, h, D;
if(!(cin >> H >> h >> D)) return 0;
auto calc = [&](double x){
double y = H + (h - H) * D / x;
if(y > 0) return (D - x) + y;
return x * h / (H - h);
};
double l = 0, r = D;
for(int it = 0; it < 100; it++){
double m1 = l + (r - l) / 3;
double m2 = r - (r - l) / 3;
if(calc(m1) < calc(m2)) l = m1;
else r = m2;
}
cout << fixed << setprecision(3) << calc((l + r) / 2) << "\n";
return 0;
}
一本通·提高篇的其它内容
- 活动安排
- 种树
- 喷水装置
- 加工生产调度
- 智力大冲浪
- 数列极差
- 数列分段
- 线段
- 家庭作业
- 钓鱼
- 糖果传递
- 愤怒的牛
- Best Cow Fences
- 曲线
- 数列分段 II
- 扩散
- 传送带
- 数的划分
- 生日蛋糕
- 小木棍
- Addition Chains
- 埃及分数
- 平板涂色
- 质数方阵
- 靶形数独
- 电路维修
- 魔板
- Knight Moves
- 棋盘游戏
- Keyboarding
- 移动玩具
- 山峰和山谷
- Oulipo
- 图书管理
- Power Strings
- Seekthe Name, Seek the Fame
- Friends
- A Horrible Poem
- Beads
- Antisymmetry
- 门票
- 收集雪花
- 剪花布条
- Power Strings
- Radio Transmission
- OKR-Periods of Words
- 似乎在梦中见过的样子
- Censoring
- Phone List
- The XOR Largest Pair
- Nikitosh 和异或
- Immediate Decodability
- L 语言
- Secret Message 秘密信息
- 背单词
- The Xor-longest Path
- Keywords Search
- 玄武密码
- Censoring
- 单词