Bzoj1502【NOI2005】月下柠檬树

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Elemmir/article/details/51447281

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

#include<bits/stdc++.h>
using namespace std;
const int maxn = 550;
const int INF  = 0x3f3f3f3f;
#define EPS  1e-6
struct 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)));


}
阅读更多
换一批

没有更多推荐了,返回首页