zoj 3203 - Light Bulb (三分)
三分第一题,,,,
题意:
某人在房间内左右走动,要求这个人的影子最大长度是多少。
思路:
明显的,人在灯下的影子长度是0,这时他如果向前走的话,影子会逐渐变长,到影子投到墙上的时候,由于情况复杂,就不考虑如果变化的了,反正到最后人走到墙的位置的时候,影长度便是人的身高了,所以影长的变化曲线要么是单调递增的【如第一组样例】要么是向上凸的【如第二、三组样例】,所以三分的方法还是比较适合的。。。
由于影长从灯下0一直到恰好没投影到墙上的过程是一个单调的过程,我们可以把这段忽略,直接求解,投影到墙上后,影长的变化即可。
代码如下:
#include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <queue> #include <stack> #include <list> #include <vector> #include <map> #include <algorithm> #define LL long long #define LLU unsigned long long #define INF 0x7fffffff #define eps 1e-7 using namespace std; double calcu(double H, double h, double D, double x) { double t = (h*D-H*x)/(H-h); return H*t/(D+t)+x; } int main () { int t; double H, h, D; scanf("%d",&t); while(t--) { scanf("%lf%lf%lf",&H, &h, &D); double l = 0, r = D*h/H; double mid, midmid, t1, t2; while(r-l>eps) { mid = (l+r)/2, midmid = (mid+r)/2; t1 = calcu(H,h,D,mid); t2 = calcu(H,h,D,midmid); if(t1>t2) r = midmid; else l = mid; } printf("%.3lf\n",calcu(H,h,D,l)); } return 0; }