链接:点击打开链接
题意:如图,人左右走动,求影子L的最长长度。根据图,很容易发现当灯,人的头部和墙角成一条直线时(假设此时人站在A点),此时的长度是影子全在地上的最长长度。当人再向右走时,影子开始投影到墙上,当人贴着墙,影子长度即为人的高度。所以当人从A点走到墙,函数是先递增再递减,为凸性函数,所以我们可以用三分法来求解
代码:
<span style="font-family:FangSong_GB2312;font-size:18px;">#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
double H,h,D;
double cal(double x){
return D-x+(h*D+H*x-H*D)/x; //相似三角形推出公式,不要忘记加D-x
}
double threesearch(double l,double r){
double mid,midmid;
int i;
for(i=0;i<100;i++){ //三分,为了避免精度问题改用for循环
mid=(r-l)/3+l;
midmid=(r-l)/3*2+l;
if(cal(mid)<cal(midmid))
l=mid;
else
r=midmid;
}
return cal(l);
}
int main(){
int t,i,j;
double temp;
cin>>t;
while(t--){
cin>>H>>h>>D;
temp=threesearch(D-D*h/H,D); //从0到D-D*h/H为单增函数,所以从D-D*h/H
printf("%.3lf\n",temp); //到D开始三分求最值,这个题也可以推公式
} //求导求最值,这里不做说明
return 0;
}
</span>