Bzoj1502【NOI2005】月下柠檬树

来源:互联网 发布:java程序员 图书 编辑:程序博客网 时间:2024/04/29 14:59

自适应Simpson积分求面积并。
平行光啊,它有个好,照下来那影子和原来平行于地面的物体是全等。于是我们就有了横向排布着的一些圆和一些线段,然后算就好了。

#include<bits/stdc++.h>using namespace std;const int maxn = 550;const int INF  = 0x3f3f3f3f;#define EPS  1e-6struct Circle {    double x,R;}C[maxn];struct Line {    double k,b;    double L,R;}line[maxn];int lines=0;int cnt;int n;double alpha,L,R;double F(double x) {    double ret = 0;    for(int i = 1; i <= lines; i++) {        if( x >= line[i].L && x <= line[i].R )             ret = max( ret, line[i].k * x + line[i].b );    }    for(int i = 1; i <= n; i++ ) {        if( x >= C[i].x-C[i].R && x <= C[i].x + C[i].R ) {            ret = max( ret , sqrt ( C[i].R * C[i].R - (x-C[i].x)*(x-C[i].x) ) );        }    }    return ret;}double Simpson(double L,double R,double mid,double FL,double FR,double FM) {    double tFL = F( (L+mid)/2), tFR = F((mid+R)/2);    double ans = (R-L)*(FL+FR+4*FM)/6;    double Lans = (mid-L)*(FL+FM+4*tFL)/6;    double Rans = (R-mid)*(FM+FR+4*tFR)/6;    if (fabs(Lans+Rans-ans) < EPS ) return ans;    return Simpson(L,mid,(L+mid)/2,FL,FM,tFL) + Simpson(mid,R,(mid+R)/2,FM,FR,tFR);}int main() {    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    scanf("%d%lf",&n,&alpha);n++;    alpha = 1.0 / tan(alpha);    C[0].x=0;    for(int i = 1; i <= n; i++) {        double x;        scanf("%lf",&x);        C[i].x = C[i-1].x + x * alpha;    }    L=INF;R=-INF;    for(int i = 1; i <= n; i++) {        scanf("%lf",&C[i].R);        L = min(L, C[i].x - C[i].R);        R = max(R, C[i].x + C[i].R);    }    for(int i = 1; i < n; i++) {        if( C[i+1].x-C[i].x - fabs(C[i+1].R-C[i].R) < EPS )  continue;        lines++;        double sina = ( C[i].R - C[i+1].R) / ( C[i].x - C[i+1].x);        double cosa = sqrt(1.0 - sina*sina);        double tana = sina / cosa;        line[lines].L = C[i].x - C[i].R * sina;        line[lines].R = C[i+1].x - C[i+1].R * sina;        line[lines].k = tana;        line[lines].b = C[i].R  * cosa - line[lines].L * tana;    }    printf("%.2lf\n",2*Simpson(L,R,(L+R)/2.0,0,0,F((L+R)/2.0)));}
0 0
原创粉丝点击