[bzoj1502]月下柠檬树
某simpson自适应积分模板题。。。
总之看题解看会的Orz http://www.cnblogs.com/DaD3zZ-Beyonder/p/5676841.html
最后%%%QY
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <cstring> 6 #include <cmath> 7 using namespace std; 8 9 10 const int N=6000; 11 const double eps=1e-5; 12 13 int n,ll; 14 double alpha,L=1e12,R=-1e12; 15 struct P{double x,y;P(double a=0,double b=0){x=a,y=b;}}; 16 struct C{double r;P o;}c[N]; 17 struct LINE{ 18 double k,b; 19 P s,t; 20 LINE(P A=P(0,0),P B=P(0,0)){ 21 s=A,t=B; 22 if(s.x>t.x)swap(s,t); 23 k=(s.y-t.y)/(s.x-t.x); 24 b=s.y-k*s.x; 25 } 26 double f(double x){return k*x+b;} 27 }l[N]; 28 double F(double x){ 29 double ret=0; 30 for(int i=1;i<=n;i++){ 31 double d=fabs(x-c[i].o.x); 32 if(d>=c[i].r)continue; 33 double len=2*sqrt(c[i].r*c[i].r-d*d); 34 ret=max(ret,len); 35 } 36 for(int i=1;i<=ll;i++) 37 if(x>=l[i].s.x&&x<=l[i].t.x)ret=max(ret,2*l[i].f(x)); 38 return ret; 39 } 40 double G(double l,double r){ 41 return (F(l)+F(r)+4*F((l+r)/2))*(r-l)/6; 42 } 43 double simpson(double l,double r){ 44 double now=G(l,r),m=(l+r)/2; 45 return fabs(now-G(l,m)-G(m,r))<eps?now:simpson(l,m)+simpson(m,r); 46 } 47 48 int main(){ 49 scanf("%d%lf",&n,&alpha); 50 for(int i=1;i<=n+1;i++){ 51 scanf("%lf",&c[i].o.x); 52 c[i].o.x=c[i-1].o.x+c[i].o.x/tan(alpha); 53 } 54 for(int i=1;i<=n;i++)scanf("%lf",&c[i].r); 55 for(int i=1;i<=n+1;i++){ 56 L=min(L,c[i].o.x-c[i].r); 57 R=max(R,c[i].o.x+c[i].r); 58 } 59 for(int i=1;i<=n;i++){ 60 double d=c[i+1].o.x-c[i].o.x; 61 if(d<fabs(c[i].r-c[i+1].r))continue; 62 double sina=(c[i].r-c[i+1].r)/d; 63 double cosa=sqrt(1-sina*sina); 64 l[++ll]=LINE( 65 P( 66 c[i].o.x+c[i].r*sina, 67 c[i].r*cosa 68 ), 69 P( 70 c[i+1].o.x+c[i+1].r*sina, 71 c[i+1].r*cosa 72 )); 73 74 } 75 printf("%.2lf\n",simpson(L,R)); 76 }