您的位置:首页 > 其它

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

2017-11-26 13:11 417 查看

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
,s
,R
;

struct tangent_line{db l,r,y[2];}t
;
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.7853981633
10.0 10.00 10.00
4.00 5.00

171.97
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: