题解:
投在地上的影子是很多圆和两圆公切线组成的梯形的面积并。
PS:圆只要和地面平行,无论光从哪个角度照射,投影都是圆
其实应该一开始应先分成若干份做simpson的。。
View Code
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <cmath> 7 8 #define N 520 9 #define EPS 1e-6 10 11 using namespace std; 12 13 int n; 14 double a[N],b[N],af,h,lt,rt; 15 16 struct C 17 { 18 double x,y,p,q; 19 }c[N]; 20 21 inline int dc( double x) 22 { 23 if (x>EPS) return 1 ; 24 else if (x<-EPS) return - 1 ; 25 return 0 ; 26 } 27 28 inline void read() 29 { 30 scanf( " %d%lf " ,&n,& af); 31 af= 1 / tan(af); 32 for ( int i= 1 ;i<=n+ 1 ;i++ ) 33 { 34 scanf( " %lf " ,& a[i]); 35 h+=a[i]; a[i]=h* af; 36 } 37 lt=a[ 1 ];rt=a[n+ 1 ]; 38 for ( int i= 1 ;i<=n;i++ ) 39 { 40 scanf( " %lf " ,& b[i]); 41 lt=min(lt,a[i]- b[i]); 42 rt=max(rt,a[i]+ b[i]); 43 } 44 } 45 46 inline void calc() 47 { 48 for ( int i= 1 ;i<=n;i++ ) 49 if (a[i+ 1 ]-a[i]>fabs(b[i+ 1 ]- b[i])) 50 { 51 c[i].x=a[i]+b[i]*(b[i]-b[i+ 1 ])/(a[i+ 1 ]- a[i]); 52 c[i].y=sqrt(b[i]*b[i]-(c[i].x-a[i])*(c[i].x- a[i])); 53 c[i].p=a[i+ 1 ]+b[i+ 1 ]*(b[i]-b[i+ 1 ])/(a[i+ 1 ]- a[i]); 54 c[i].q=sqrt(b[i+ 1 ]*b[i+ 1 ]-(c[i].p-a[i+ 1 ])*(c[i].p-a[i+ 1 ])); 55 } 56 } 57 58 inline double f( double p) 59 { 60 double res= 0 ; 61 for ( int i= 1 ;i<=n;i++ ) 62 { 63 if (fabs(a[i]-p)<b[i]) res=max(res,sqrt(b[i]*b[i]-(a[i]-p)*(a[i]- p))); 64 if (p>c[i].x&&p<c[i].p) res=max(res,c[i].y-(p-c[i].x)*(c[i].y-c[i].q)/(c[i].p- c[i].x)); 65 } 66 return res; 67 } 68 69 inline double simpson( double l, double r, double fl, double fmid, double fr) 70 { 71 return (fl+fr+ 4 *fmid)*(r-l)/ 6 ; 72 } 73 74 inline double rsimpson( double l, double r, double fl, double fmid, double fr) 75 { 76 double p,q,mid,x,y,z; 77 mid=(l+r)/ 2 ; 78 p=f((l+mid)/ 2 ); q=f((mid+r)/ 2 ); 79 x=simpson(l,r,fl,fmid,fr); y=simpson(l,mid,fl,p,fmid); z= simpson(mid,r,fmid,q,fr); 80 if (dc(fabs(x-y-z))== 0 ) return y+ z; 81 else return rsimpson(l,mid,fl,p,fmid)+ rsimpson(mid,r,fmid,q,fr); 82 } 83 84 inline void go() 85 { 86 calc(); 87 printf( " %.2lf\n " , 2 *rsimpson(lt,rt, 0 ,f(lt+rt)/ 2 , 0 )); 88 } 89 90 int main() 91 { 92 read(),go(); 93 return 0 ; 94 }