[BZOJ 1502][NOI2005]月下柠檬树(自适应Simpson积分)

Description

李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理。
李哲是一个喜爱思考的孩子,当他看到在月光的照射下柠檬树投在地面上的影子是如此的清晰,马上想到了一个问题:树影的面积是多大呢?
李哲知道,直接测量面积是很难的,他想用几何的方法算,因为他对这棵柠檬树的形状了解得非常清楚,而且想好了简化的方法。
李哲将整棵柠檬树分成了 n 层,由下向上依次将层编号为 1,2,...,n。从第 1到 n-1 层,每层都是一个圆台型,第 n
层(最上面一层)是圆锥型。对于圆台型,其上下底面都是水平的圆。对于相邻的两个圆台,上层的下底面和下层的上底面重合。第 n
层(最上面一层)圆锥的底面就是第 n-1
层圆台的上底面。所有的底面的圆心(包括树顶)处在同一条与地面垂直的直线上。李哲知道每一层的高度为h1,h2,...,hn,第 1
层圆台的下底面距地面的高度为 h0,以及每层的下底面的圆的半径 r1,r2,...,rn。李哲用熟知的方法测出了月亮的光线与地面的夹角为
alpha。

Solution

本来只是想顺手找道计算几何做,结果被虐虐虐虐虐…细节杀*2

平行光在圆上的投影还是它本身的样子,于是变成了一堆圆和相邻圆的公切线组成的图形(还有一个尖顶)

得到了一个类似这样的东西

可以用辛普森积分算它一半的面积

具体实现什么的还是见代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define pi acos(-1)
using namespace std;
int n;
double alpha,h[505];
struct point{
    double x,y;
    point(double x=0,double y=0):x(x),y(y){}
}line[505][2];
struct circle{
    point c;double r;
    circle(point c=point(0,0),double r=0):c(c),r(r){}
    point getpoint(double ang){
        return point(c.x+r*cos(ang),c.y+r*sin(ang));
    }
}lemon[505];
void getline(circle a,circle b,point& p,point& q)
{
    if(a.r<b.r)swap(a,b);
    if((a.r-b.r)>=fabs(a.c.x-b.c.x))return;
    double ang=acos((a.r-b.r)/fabs(a.c.x-b.c.x));
    if(a.c.x<=b.c.x)p=a.getpoint(ang),q=b.getpoint(ang);
    else q=a.getpoint(pi-ang),p=b.getpoint(pi-ang);
}
double pow(double x){return x*x;}
double f(double x)
{
    double res=0;
    for(int i=0;i<n;i++)
    if(line[i][0].x<=x&&line[i][1].x>=x){
        res=max(res,(x-line[i][0].x)*(line[i][1].y-line[i][0].y)/(line[i][1].x-line[i][0].x)+line[i][0].y);
    }
    for(int i=0;i<=n;i++){
        if(pow(lemon[i].r)-pow(lemon[i].c.x-x)>=0)
        res=max(res,sqrt(pow(lemon[i].r)-pow(lemon[i].c.x-x)));
    }
    return res;
}
double simpson(double a,double b){
    double c=a+(b-a)/2;
    return (f(a)+4*f(c)+f(b))*(b-a)/6;
}
double asr(double a,double b,double eps,double A){
    double c=a+(b-a)/2;
    double l=simpson(a,c),r=simpson(c,b);
    if(fabs(l+r-A)<=15*eps)return l+r+(l+r-A)/15.0;
    return asr(a,c,eps/2,l)+asr(c,b,eps/2,r);
}
double asr(double a,double b,double eps){
    return asr(a,b,eps,simpson(a,b));
}
int main()
{
    scanf("%d%lf",&n,&alpha);
    double s=0;
    for(int i=0;i<=n;i++){
        scanf("%lf",&h[i]);
        s+=h[i];
        h[i]=s/tan(alpha);
    }
    double r,minn=1000000000,maxn=0;
    for(int i=0;i<=n;i++){
        if(i!=n)scanf("%lf",&r);
        else r=0;
        maxn=max(maxn,h[i]+r);
        minn=min(minn,h[i]-r);
        lemon[i]=circle(point(h[i],0),r);
    }
    for(int i=0;i<n;i++){
        getline(lemon[i],lemon[i+1],line[i][0],line[i][1]);
    }
    printf("%.2lf\n",2*asr(minn,maxn,1e-7));
    return 0;
} 

And all that I can see.
And all that I can see.
And all that I can see is just a lemon tree.

时间: 2024-10-15 23:00:01

[BZOJ 1502][NOI2005]月下柠檬树(自适应Simpson积分)的相关文章

BZOJ 1502 [NOI2005]月下柠檬树 自适应Simpson积分

题意:链接 方法:自适应Simpson积分 解析: 大半夜刷这道题真是爽歪歪. 求一棵树(圆锥加圆台组成)在平面上的投影的面积. 给定投影角度(0.3 < alpha <= pi/2). 先来想想圆的投影是什么样子 还是他自己. 再想圆锥投影是什么样子 一个点加一个圆,并且有这个点与该圆的两条切线(该点在圆内部时没有切线) 再想圆台 两个圆,加上两个圆的外公切线组成的一坨图形. 不妨随意画一个. 好难画- -! 大概就转化成这个样子了. 观察这个图形- 轴对称啊- -! 这意味着我们好多东西都

BZOJ 1502: [NOI2005]月下柠檬树 [辛普森积分 解析几何 圆]

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1070  Solved: 596[Submit][Status][Discuss] Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度.第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的

BZOJ 1502 NOI2005 月下柠檬树 Simpson自适应公式

题目大意:给定一棵由圆台和圆锥构成的柠檬树,月光以α的夹角平行射向地面,求阴影部分面积 补充题目大意:看到这题我产生了心理阴影,求阴影部分面积 题目不好分析,但其实就是求一堆圆和一堆梯形的面积交 样例如图(画的有点烂),将顶点看做半径为0的圆,则图中圆的半径即为给定圆的半径,圆心距为h/tan(α),直线为两圆公切线 这题我们采用辛普森自适应公式 首先辛普森公式见度受百科 http://baike.baidu.com/view/2710883.htm?fr=aladdin 比较遗憾的是 辛普森公

BZOJ 1502:月下柠檬树

BZOJ 1502:月下柠檬树 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题目大意:给出一棵有圆台构成的树以及一个平行光源,问树的阴影面积. 计算几何 Simpson积分 第一次写计算几何题,一直wa...明天补

[BZOJ1502]月下柠檬树(自适应辛普森积分)

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1387  Solved: 739[Submit][Status][Discuss] Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地 坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理.李哲是一个喜爱思考的孩子,当他看到在月光的照射下 柠檬树投在地面上的影子是如此的清晰,马上想到了一个问

bzoj 1502 月下柠檬树【Simpson积分】

投影到地面之后,会发现圆形在平行光下面积和形状是不会变的,也就是所要求的图形是若干个圆和把相邻两个圆连起来的公切线所组成的. 公切线和圆间距瞎求一下就行,注意要去掉被完全覆盖的圆 然后simpson即可 eps大概1e-6 #include<iostream> #include<cstdio> #include<cmath> using namespace std; const int N=1005; const double eps=1e-6,inf=1e15; do

[NOI2005]月下柠檬树[计算几何(simpson)]

1502: [NOI2005]月下柠檬树 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1169  Solved: 626[Submit][Status][Discuss] Description Input 文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度).第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度.第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的

【BZOJ1502】[NOI2005]月下柠檬树 Simpson积分

[BZOJ1502][NOI2005]月下柠檬树 Description 李哲非常非常喜欢柠檬树,特别是在静静的夜晚,当天空中有一弯明月温柔地照亮地面上的景物时,他必会悠闲地坐在他亲手植下的那棵柠檬树旁,独自思索着人生的哲理.李哲是一个喜爱思考的孩子,当他看到在月光的照射下柠檬树投在地面上的影子是如此的清晰,马上想到了一个问题:树影的面积是多大呢?李哲知道,直接测量面积是很难的,他想用几何的方法算,因为他对这棵柠檬树的形状了解得非常清楚,而且想好了简化的方法.李哲将整棵柠檬树分成了n 层,由下向

[日常摸鱼]bzoj1502[NOI2005]月下柠檬树-简单几何+Simpson法

关于自适应Simpson法的介绍可以去看我的另一篇blog http://www.lydsy.com/JudgeOnline/problem.php?id=1502 题意:空间里圆心在同一直线上且底面与地面平行的若干个圆台和顶层的圆锥以$\alpha$的角度投影到地面,求投影的面积. (其实我是看po姐博客来的x) 首先把圆锥的顶点也看成一个半径为0的圆满,对于每个高度为$h$的圆投影下去的坐标是$h/tan(\alpha)$,半径不变,而对于圆台的侧面投影下去是上下底两个圆的切线. 关于两个圆