月下柠檬树

题意

求n个圆与他们的公切线的定积分。

解法

求出圆的公切线就可以了。

特别坑的一点

最两端的圆,有可能会被其他的圆所包含,所以要重新求一下最左端与最右端。

比较坑的一点

精度要设小一点,不然会TLE。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>
#define INF 2139062143
#define MAX 0x7ffffffffffffff
#define del(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
x=0;T k=1;char c=getchar();
while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
}
const int maxn=(500+5)*2;
struct cir{
double x,r;
double h(double k){
double d=fabs(k-x);
return sqrt(r*r - d*d);
}
}c[maxn];
struct lin{
// y=kx+b
double k,b,lx,ly;
double h(double x){
return x*k+b;
}
}p[maxn];
int n;
double F(double x){
double ans=0.0;
for(int i=1;i<=n;i++){
if(x>(c[i].x-c[i].r)&&x<(c[i].x+c[i].r))
ans=max(ans,c[i].h(x));
}
for(int i=1;i<n;i++){
if(x>=p[i].lx&&x<=p[i].ly)
ans=max(ans,p[i].h(x));
}
return ans;
}
double simpson(double a,double b){
double mid=(a+b)/2;//*0.5???
return ( F(a) + 4*F(mid) + F(b) ) * (b-a)/6;
}
double asr(double a,double b,double eps,double A){
double mid = (a+b)/2;
double L = simpson(a,mid) , R = simpson(mid,b);
if(fabs(L+R-A) <= 15*eps) return L+R+(L+R-A)/15;
return asr(a,mid,eps/2,L) + asr(mid,b,eps/2,R);
}
double asr(double l,double r,double eps){
return asr(l,r,eps,simpson(l,r));
}
double alpha;
double h[maxn];
int main()
{
scanf("%d%lf",&n,&alpha);n++;
alpha= 1.0 / tan(alpha);
for(int i=1;i<=n;i++) scanf("%lf",&h[i]);
for(int i=1;i<n;i++) scanf("%lf",&c[i].r);c[n].r=0.0;
for(int i=1;i<=n;i++) c[i].x=c[i-1].x+h[i];
for(int i=1;i<=n;i++) c[i].x*=alpha; for(int i=1;i<n;i++){
if((c[i+1].x+c[i+1].r)<=(c[i].x+c[i].r)) continue;
if(fabs(c[i].r-c[i+1].r)<=1e-6){
p[i].lx=c[i].x,p[i].ly=c[i+1].x;
p[i].k=0.0;p[i].b=c[i].r;
continue;
}
if(c[i].r<c[i+1].r){
double _cos=(c[i+1].r-c[i].r)/(c[i+1].x-c[i].x);
double d=_cos*c[i+1].r;
double y2 = sqrt(c[i+1].r*c[i+1].r - d*d);
p[i].ly=c[i+1].x-d;
d=_cos*c[i].r;
double y1 = sqrt(c[i].r*c[i].r - d*d);
p[i].lx=c[i].x-d;
p[i].k = (y1-y2)/(p[i].lx-p[i].ly);
p[i].b = y1 - p[i].k*p[i].lx;
}
else{
double _cos=(c[i].r-c[i+1].r)/(c[i+1].x-c[i].x);
double d=_cos*c[i].r;
p[i].lx=c[i].x+d;
double y1 = sqrt(c[i].r*c[i].r - d*d);
d=_cos*c[i+1].r;
double y2 = sqrt(c[i+1].r*c[i+1].r - d*d);
p[i].ly=c[i+1].x+d;
p[i].k = (y1-y2)/(p[i].lx-p[i].ly);
p[i].b = y1 - p[i].k*p[i].lx;
}
}
//*****
double ll=c[1].x-c[1].r,rr=c[n].x;
for(int i=1;i<=n;i++){
double l=c[i].x-c[i].r,r=c[i].x+c[i].r;
ll=min(l,ll);rr=max(rr,r);
}
printf("%.2lf",2*asr(ll,rr,1e-6));
return 0;
}

最新文章

  1. Javascript数据类型检测
  2. 强大的JavaScript动画图形库mo.js
  3. ACM/ICPC 之 DP-基因相似度(POJ1080-ZOJ1027)
  4. document.cookie的使用
  5. C#获取根目录的方法集合
  6. 转载sublime text3中package Control
  7. web前端开发(3)
  8. createjs 下雪 实例
  9. 关于Python文档读取UTF-8编码文件问题
  10. 转载:Java连接MySQL 数据库的正确操作流程
  11. iOS多线程总结(一)NSThread
  12. 模版引擎Handlebars语法(1)
  13. flask配置管理
  14. Android中怎样获取SD卡路径
  15. JAVA\Android 多线程实现方式及并发与同步
  16. Jmeter启动默认中文
  17. css关于浮动的高度塌陷
  18. 【BZOJ3874】[AHOI&amp;JSOI2014]宅男计划(贪心,三分)
  19. mysql拿webshell总结
  20. python venv actieve uninstall pack-name sitepage

热门文章

  1. LCIS 最长公共上升子序列问题DP算法及优化
  2. [luogu4151 WC2011] 最大XOR和路径 (线性基)
  3. C#通过SendMessage发送消息,改变其他程序的下拉框控件(ComboBox)的值
  4. Tensorflow 之物体检测
  5. BZOJ 3674 可持久化并查集加强版(按秩合并版本)
  6. 洛谷 P1124 文件压缩
  7. SDWebImage源代码解析(二)
  8. iOS中的crash防护(二)KVC造成的crash
  9. mysql点滴_02程序中运行sql语句报字符集问题解决
  10. mysql基础综述(四)