1. 程式人生 > >ZOJ 3203 燈泡

ZOJ 3203 燈泡

itl 之間 三分法 \n leo width 但是 詳細 main

題面

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

思路

首先,分治肯定是能夠想到的,但是是二分還是三分呢,我們只需要思考一下就能知道,我們設地上影長為L1,墻上為L2,人走近時L1增加,L2減小,走遠時L1減小,L2增加——這是個二次函數,所以一定使用三分法。
然後讓我們來算L的長度,首先L1=D-X(X為人到左墻距離),L2=H-(H-h)*D/X(相似三角形)。


如果不理解可看下圖 ,兩個藍的三角形為相似三角形,對應邊的比值相同。
然後三分一下x的範圍即可。
技術分享圖片

代碼

 1 (我都講得這麽詳細了還需要代碼?)
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 double H,h,D,mid1,mid2;
 5 int t; 
 6 double check(double x)
 7 {
 8     return D-x+H-(H-h)*D/x;
 9 }
10 int main()
11 {
12     cin>>t;
13     while (t--)
14     {
15 cin>>H>>h>>D; 16 double l=(H-h)*D/H,r=D;//註意l要從(H-h)*D/H開始,不然墻上沒有影子。 17 while (l+1e-10<=r) 18 { 19 mid1=(l+r)/2; 20 mid2=(mid1+r)/2; 21 if (check(mid1)>=check(mid2)) r=mid2;else l=mid1; 22 } 23 printf("
%.3lf\n",check(mid1)); 24 } 25 return 0; 26 }

ZOJ 3203 燈泡