【C++】「一本通 1.2 練習 3」燈泡(Light Bulb)

【來源】

一本通題庫-1438
LibreOJ-10016
ZOJ-3203
vjudge

【題目描述】

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.

相比 wildleopard 的家,他的弟弟 mildleopard 比較窮。他的房子是狹窄的而且在他的房間裏面僅有一個燈泡。每天晚上,他徘徊在自己狹小的房子裏,思考如何賺更多的錢。有一天,他發現他的影子的長度隨着他在燈泡和牆壁之間走到時發生着變化。一個突然的想法出現在腦海裏,他想知道他的影子的最大長度。
在這裏插入圖片描述

【輸入格式】

The first line of the input contains an integer T(T<=100)T (T <= 100), indicating the number of cases.

Each test case contains three real numbers HH, hh and DD in one line. HH is the height of the light bulb while hh is the height of mildleopard. DD is distance between the light bulb and the wall. All numbers are in range from 10210^{-2} to 10310^3, both inclusive, and Hh>=102H - h >= 10^{-2}.

輸入文件的第一行包含一個整數 TT ,表示測試數據的組數。

對於每組測試數據,僅一行,包含三個實數 HHhhDDHH 表示燈泡的高度,hh 表示 mildleopard 的身高,DD 表示燈泡和牆的水平距離。

【輸出格式】

For each test case, output the maximum length of mildleopard’s shadow in one line, accurate up to three decimal places…

輸出文件共 TT 行,每組數據佔一行表示影子的最大長度,保留三位小數。

【樣例輸入】

3
2 1 0.5
2 0.5 3
4 3 4

【樣例輸出】

1.000
0.750
4.000

【數據範圍】

T100T≤100102H,h,D10310^{−2}≤H,h,D≤10^3102Hh10^{−2}≤H−h

【解析】

三分。
當人從牆上剛有影子處向右一直走到牆的過程中,影子總長是關於牆上影子的凸函數。
即求函數 f(x)=hDHxDx+xf(x)=\frac{h*D-H*x}{D-x}+x(也可以是f(x)=Dx+HD(Hh)xf(x)=D-x+H-\frac{D*(H-h)}{x}) 的最大值。
三分牆上的影子長。

【代碼】

#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>

#define RI                 register int
#define re(i,a,b)          for(RI i=a; i<=b; i++)
#define ms(i,a)            memset(a,i,sizeof(a))
#define MAX(a,b)           (((a)>(b)) ? (a):(b))
#define MIN(a,b)           (((a)<(b)) ? (a):(b))

using namespace std;

typedef long long LL;

const int N=105;
const int inf=1e9;

int T;
double H,h,D;

double calc(double x) {
	return D-x+H-D*(H-h)/x;
}

int main() {
	scanf("%d",&T);
	while(T--) {
		scanf("%lf%lf%lf",&H,&h,&D);
		double l=D-D*h/H,r=D;
		while(r-l>1e-12) {
			double lmid=l+(r-l)/3;
			double rmid=r-(r-l)/3;
			if(calc(lmid)<calc(rmid)) l=lmid;
				else r=rmid;
		}
		printf("%0.3f\n",calc(l));
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章