BZOJ 1502: [NOI2005]月下柠檬树 simpson积分

来源:互联网 发布:淘宝云客服兼职 编辑:程序博客网 时间:2024/05/01 16:54

1502: [NOI2005]月下柠檬树

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1244  Solved: 662
[Submit][Status][Discuss]

Description

Input

文件的第1行包含一个整数n和一个实数alpha,表示柠檬树的层数和月亮的光线与地面夹角(单位为弧度)。第2行包含n+1个实数h0,h1,h2,…,hn,表示树离地的高度和每层的高度。第3行包含n个实数r1,r2,…,rn,表示柠檬树每层下底面的圆的半径。上述输入文件中的数据,同一行相邻的两个数之间用一个空格分隔。输入的所有实数的小数点后可能包含1至10位有效数字。

Output

输出1个实数,表示树影的面积。四舍五入保留两位小数。

Sample Input

2 0.7853981633
10.0 10.00 10.00
4.00 5.00

Sample Output

171.97

HINT

1≤n≤500,0.3


这个图好炸了http://blog.csdn.net/wzq_QwQ/article/details/48310417

圆无论怎么搞 还是原来的圆 就是换了位置

圆台的话 就是在上下两个圆之间 加个公切线

可以用simpson积分做 虽然 我觉得很容易卡掉。。。

共切线可以用相似三角形搞


#include<cmath>#include<ctime>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>#include<iomanip>#include<vector>#include<string>#include<bitset>#include<queue>#include<set>#include<map>using namespace std;typedef double db;inline int read(){int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}return x*f;}void print(int x){if(x<0)putchar('-'),x=-x;if(x>10)print(x/10);putchar(x%10+'0');}const int N=510,inf=0X3f3f3f3f;const db eps=1e-6;int lala(int a,int b){return max(a,b);}int n;db alpha,h[N],s[N],R[N];struct tangent_line{db l,r,y[2];}t[N];int tot;inline db f(db x){db res=0;for(int i=1;i<=n;++i)if(s[i]-R[i]<x&&s[i]+R[i]>x)res=max(res,sqrt(R[i]*R[i]-(s[i]-x)*(s[i]-x)));for(int i=1;i<=tot;++i)if(t[i].l<x&&t[i].r>x)res=max(res,t[i].y[0]+(t[i].y[1]-t[i].y[0])*(x-t[i].l)/(t[i].r-t[i].l));return res;}inline db cal(db fl,db fr,db fmid){return (fl+fr+4*fmid)/6.0;}db simpson(db l,db r,db mid,db fl,db fr,db fmid){db res=cal(fl,fr,fmid)*(r-l);db resl=f((l+mid)/2.0);db resr=f((mid+r)/2.0);if(abs(cal(fl,fmid,resl)*(mid-l)+cal(fmid,fr,resr)*(r-mid)-res)<eps)return res;return simpson(l,mid,(l+mid)/2.0,fl,fmid,resl)+simpson(mid,r,(mid+r)/2.0,fmid,fr,resr);}int main(){n=read();scanf("%lf",&alpha);alpha=1/tan(alpha);for(int i=1;i<=n+1;++i){scanf("%lf",&h[i]);h[i]+=h[i-1];s[i]=h[i]*alpha;}db l=inf,r=-inf;for(int i=1;i<=n;++i){scanf("%lf",&R[i]);l=min(l,s[i]-R[i]);r=max(r,s[i]+R[i]);}r=max(r,s[n+1]);for(int i=1;i<=n;++i)if(abs(R[i]-R[i+1])<s[i+1]-s[i]){db d=s[i+1]-s[i];t[++tot].l=s[i]+R[i]*(R[i]-R[i+1])/d;t[tot].y[0]=sqrt(R[i]*R[i]-(t[tot].l-s[i])*(t[tot].l-s[i]));t[tot].r=s[i+1]+R[i+1]*(R[i]-R[i+1])/d;t[tot].y[1]=sqrt(R[i+1]*R[i+1]-(t[tot].r-s[i+1])*(t[tot].r-s[i+1]));}printf("%.2lf\n",2*simpson(l,r,(l+r)/2.0,0,0,f((l+r)/2.0)));return 0;}/*2 0.785398163310.0 10.00 10.004.00 5.00171.97*/

原创粉丝点击