ZOJ - 3203 Light Bulb

这里加了点人工的分析,写出这个判断的流程。 为了避免比较时的浮点数误差,我都改成乘的了。

不过我试了下,这里不用这样也是没问题的。但是我还是觉得这样会好些。

 

 

影子的公式,我是根据两对全等三角形得出的。数学太差了。。 看不懂javaman的解题报告上说的 “

   设影子打到墙上长为L,则有

(D-x)*H+L*x=h*D  (这个式子就是定比分点)

 

#include <cstdio> #include <cmath> #define max(a, b) (a > b ? a : b) int main(int argc, char* argv[]) { int T; double H, h, D, a1, a2, tx, begin; scanf("%d", &T); while(T--) { scanf("%lf%lf%lf", &H, &h, &D); begin = D-D*h/H; a1 = D*h/H; tx = (H-h)*D; if(tx >= begin*begin && tx <= D*D) { a2 = H+D-2*sqrt((H-h)*D); } else { if(D*D <= tx) { a2 = h; } else if(begin*begin >= tx){ a2 = h*D/H; } } printf("%.3lf/n", max(a1, a2)); } return 0; } 

 

下面这个代码发挥了计算机的优势了,像二分查找一样,这里采用三分。

 

#include <cstdio> #include <cmath> #define max(a, b) (a > b ? a : b) double H, h, D, l, r; double yz_length(double x) { return H+D - (H-h)*D/x - x; } int main(int argc, char* argv[]) { int T; scanf("%d", &T); while(T--) { scanf("%lf%lf%lf", &H, &h, &D); l = D-D*h/H; r = D; while(r-l > 1e-9) { double mid1 = l+(r-l)/3; double mid2 = r-(r-l)/3; //double mid1 = (r+l)/2; //double mid2 = (r+mid1)/2; if(yz_length(mid1) > yz_length(mid2)) { r = mid2; } else { l = mid1; } } printf("%.3lf/n", yz_length(l)); } return 0; } 

你可能感兴趣的:(ZOJ - 3203 Light Bulb)