BZOJ 1502 月下柠檬树 simpson积分

题解:
投在地上的影子是很多圆和两圆公切线组成的梯形的面积并。

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 }

 

 

你可能感兴趣的:(imp)