zoukankan      html  css  js  c++  java
  • 【bzoj1502】 NOI2005—月下柠檬树

    http://www.lydsy.com/JudgeOnline/problem.php?id=1502 (题目链接)

    今天考试题,从来没写过圆的面积之类的东西。。GG

    题意

      一颗树由n个圆台组成,现在有倾斜角为alpha的光,不计树干阴影,光线沿直线传播,求这个树在水平地面投影的面积。

    Solution

      Simpson积分法。

      直接蒯一份题解算了(http://blog.csdn.net/ww140142/article/details/48296273),反正也看不懂。。看来只能背代码了

      给出一颗树。。求这棵树的阴影面积。。。 
      什么鬼题!= = 
      当然这是一道计算几何; 
      首先我们把树的尖看成半径为0的圆; 
      三维图形到二维的投影貌似很难啊,不过这题也有很多特殊性; 
      因为圆对于平行的面的投影都是相同的正圆,所以可以直接投在地面上; 
      而圆心距则是除了一个tan函数的样子,所以圆已经被扔到待求的平面上了; 
      这些圆的公切线!(这样就从母的变成公的啦233) 
      公切线的求法就是画图上勾股定理相似乱搞,调两组数据改改就好了; 
      然后正解似乎是讨论了一堆东西然后分别求面积; 
      然后我们似乎可以直接上Simpson积分! 
      具体细节不说了,代码里都有; 
      这题精度不是特别卡,EPS=1e5就够了?

      当然,我写的是1e7= =。

    代码

    // bzoj1502
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #define eps 1e-7
    #define inf 2147483640
    #define LL long long
    #define free(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout);
    using namespace std;
    inline LL getint() {
        LL x=0,f=1;char ch=getchar();
        while (ch>'9' || ch<'0') {if (ch=='-') f=-1;ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    const int maxn=510;
    struct S {double x,y,p,q;}c[maxn];
    double h[maxn],s[maxn],r[maxn],alpha,ll,rr;
    int n,size=0;
    
    double sqr(double x) {return x*x;}
    double f(double l) {
        double t=0.0;
        for (int i=1;i<=n;i++)
            if (fabs(s[i]-l)<r[i]) t=max(t,sqrt(sqr(r[i])-sqr(s[i]-l)));
        for (int i=1;i<=size;i++)
            if (c[i].x<l && l<c[i].p) t=max(t,c[i].y+(c[i].q-c[i].y)*(l-c[i].x)/(c[i].p-c[i].x));
        return t;
    }
    double Simpson(double l,double r,double fl,double fmid,double fr) {
        double m=(l+r)/2;
        double p=f((l+m)/2),q=f((m+r)/2);
        double x=(fl+4*fmid+fr)*(r-l)/6,y=(fl+4*p+fmid)*(m-l)/6,z=(fmid+4*q+fr)*(r-m)/6;
        if (fabs(x-y-z)<eps) return y+z;
        return Simpson(l,m,fl,p,fmid)+Simpson(m,r,fmid,q,fr);
    }
    int main() {
        scanf("%d%lf",&n,&alpha);
        alpha=1.0/tan(alpha);
        for (int i=1;i<=n+1;i++) {
            scanf("%lf",&h[i]);
            h[i]+=h[i-1];
            s[i]=h[i]*alpha;
        }
        ll=0;rr=0;
        for (int i=1;i<=n;i++) {
            scanf("%lf",&r[i]);
            ll=min(ll,s[i]-r[i]);
            rr=max(rr,s[i]+r[i]);
        }
        r[n+1]=0;
        for (int i=1;i<=n;i++) {
            double d=s[i+1]-s[i];
            if (d>fabs(r[i]-r[i+1])) {
                c[++size].x=s[i]-r[i]*(r[i+1]-r[i])/d;
                c[size].y=sqrt(sqr(r[i])-sqr(c[size].x-s[i]));
                c[size].p=s[i+1]-r[i+1]*(r[i+1]-r[i])/d;
                c[size].q=sqrt(sqr(r[i+1])-sqr(c[size].p-s[i+1]));
            }
        }
        rr=max(rr,s[n+1]);
        printf("%.2lf",2*Simpson(ll,rr,0,f((ll+rr)/2),0));
        return 0;
    }
    

      

  • 相关阅读:
    js对象排序
    路由懒加载优化
    RabbitMQ---1、安装与部署
    RabbitMQ入门教程系列
    c#项目代码风格要求
    C#RabbitMQ基础学习笔记
    C# 协变和逆变
    获取当前系统的基本信息
    html制作chm格式开源文档
    WPF: RenderTransform特效
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5914116.html
Copyright © 2011-2022 走看看