Light Bulb ZOJ

来源:互联网 发布:类似于知乎的app 编辑:程序博客网 时间:2024/06/06 07:16

题意如下:
有一个高H的灯,在灯的右边D距离有一堵墙,在灯和墙之间有一个高h人,h小于H。问人的影子最多有多长。如下图求L

这是题中的图

高中物理题,相信学霸可以用公式退出来,不过也会挺费事。我们用三分查找可以轻松求解。

首先我们要证明影子随着人向右走,是一个先增后减的单峰函数。 这个是常识 0.0 。大致推理一下,如果没有墙 ,影子是越来越长的,有了墙,使得本该极长的影子,有了上限人的高度。 可能服从单峰函数,当然不一定是真的,然后我们写出求影长的公式 f(x) ,一不小心发现确实是单峰函数,然后果断三分查找啊,

#include<cstdio>#include<algorithm>#include<cmath>#include<iostream>using namespace std;const double esp=0.00000001;double H,h,d;//这里是f(x) 一个单峰函数 凸的, double f(double x){    //   H/h=(x+a)/a;相似三角形    double a= (h*x)/(H-h);//如果没有墙时的影长     if(a>d-x){//如果墙上有影子         double b= (a-(d-x))/a*h;//墙上影子的长度         a=a-(a-(d-x))+b;//影子的总长度     }    return a; }//这里是三分的内容 double oneThird(double l,double r){    while(r-l>esp){        double mid=l+(r-l)/2;        double mmid=mid+(r-mid)/2;        if(f(mid)>f(mmid)){            r=mmid;        }        else l=mid;    }    return l;}int main(){    int t;    scanf("%d",&t);    while(t--){        scanf("%lf%lf%lf",&H,&h,&d);        printf("%.3lf\n",f( oneThird(0.01,d) ) );    }    return 0;} 

挺简单的对吧
里面有个很蛋疼的地方,三分区间不能从零开始,我 wrong 了好几次就是因为0。感觉可能是f(x)的一些原因,但谁知道呢

原创粉丝点击