题解:
投在地上的影子是很多圆和两圆公切线组成的梯形的面积并。
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
}

