题面

传送门

题解

对于每个圆,我们单独计算它被覆盖的周长是多少

只有相交的情况需要考虑,我们需要知道相交的那段圆弧的角度,发现其中一个交点和两个圆的圆心可以构成一个三角形且三边都已经知道了,那么我们可以根据余弦定理计算出这段圆弧的余弦进而用\(acos\)计算出角度

然而现在有个尴尬的问题是一段圆弧可能会被多次覆盖。那么我们考虑把相交的圆弧的左右端点用极角来表示,并把这个看成一条线段,那么最后只要求出线段覆盖就行了

顺便注意转化为极角的时候如果极角是负的要加上\(2\pi\),如果这时候\(l>r\),就拆成\([l,2\pi]+[2\pi,r]\)的形式

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
double readdb()
{
R double x=0,y=0.1,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(x=ch-'0';(ch=getc())>='0'&&ch<='9';x=x*10+ch-'0');
for(ch=='.'&&(ch=getc());ch>='0'&&ch<='9';x+=(ch-'0')*y,y*=0.1,ch=getc());
return x*f;
}
const int N=2005;const double Pi=acos(-1.0);
struct point{double r,x,y;}p[N];
struct node{
double l,r;
node(){}
node(R double ll,R double rr):l(ll),r(rr){}
inline bool operator <(const node &b)const{return l<b.l;}
}st[N];
int n,top;double res;
inline double dis(R int i,R int j){return sqrt((p[i].x-p[j].x)*(p[i].x-p[j].x)+(p[i].y-p[j].y)*(p[i].y-p[j].y));}
inline int in(R int i,R int j){return p[j].r>=p[i].r+dis(i,j);}
void calc(int pos){
fp(i,pos+1,n)if(in(pos,i))return;
top=0;
fp(i,pos+1,n){
R double d=dis(pos,i);if(in(i,pos)||p[i].r+p[pos].r<=d)continue;
R double t=acos((d*d+p[pos].r*p[pos].r-p[i].r*p[i].r)/(2*p[pos].r*d));
R double b=atan2(p[i].y-p[pos].y,p[i].x-p[pos].x);
st[++top]=node(b-t,b+t);
st[top].l<0?st[top].l+=2*Pi:0;
st[top].r<0?st[top].r+=2*Pi:0;
st[top].l>st[top].r?(st[top+1]=node(0,st[top].r),st[top++].r=2*Pi):0;
}
sort(st+1,st+1+top);
R double now=0,tmp=0;
fp(i,1,top)now<st[i].l?(tmp+=st[i].l-now,now=st[i].r):cmax(now,st[i].r);
res+=p[pos].r*(tmp+2*Pi-now);
}
int main(){
// freopen("testdata.in","r",stdin);
n=read();
fp(i,1,n)p[i].r=readdb(),p[i].x=readdb(),p[i].y=readdb();
fp(i,1,n)calc(i);
printf("%.3lf\n",res);
return 0;
}

洛谷P2510 [HAOI2008]下落的圆盘(计算几何)的更多相关文章

  1. bzoj1043[HAOI2008]下落的圆盘 计算几何

    1043: [HAOI2008]下落的圆盘 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1598  Solved: 676[Submit][Stat ...

  2. luogu P2510 [HAOI2008]下落的圆盘

    LINK:下落的圆盘 计算几何.n个圆在平面上编号大的圆将编号小的圆覆盖求最后所有没有被覆盖的圆的边缘的总长度. 在做这道题之前有几个前置知识. 极坐标系:在平面内 由极点 极轴 和 极径组成的坐标系 ...

  3. 【bzoj1043】[HAOI2008]下落的圆盘 计算几何

    题目描述 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. 输入 第一行为1个整数n,N<=1000接下来n行每行3个实 ...

  4. BZOJ 1043 HAOI2008 下落的圆盘 计算几何

    题目大意:n个圆盘依次下落.求终于能看到的轮廓线面积 円盘反对! 让我们一起团结起来! 赶走円盘! 咳咳.非常神的一道题 今天去看了题解和白书才搞出来-- 首先我们倒着做 对于每一个圆盘处理出在它之后 ...

  5. BZOJ 1043 [HAOI2008]下落的圆盘 ——计算几何

    倒着考虑,加入一个圆,判断和前面有没有完全覆盖的情况. 如果没有,和圆盘一一取交集,然后计算它们的并集,然后计算即可. #include <map> #include <cmath& ...

  6. JZYZOJ1502 [haoi2008]下落的圆盘 计算几何 贪心

    http://172.20.6.3/Problem_Show.asp?id=1502这种题用了快一天才写出来也是真的辣鸡.主要思路就是计算一下被挡住的弧度然后对弧度进行贪心.最开始比较困扰的是求弧度值 ...

  7. P2510 [HAOI2008]下落的圆盘

    传送门 首先考虑两个圆覆盖的情况,我们可以求出圆心与交点连线 $A$ 的极角 具体就是求出两圆心连线 $B$ 极角加上余弦定理加反余弦求出 $A,B$ 之间夹角 ,然后覆盖了多少就可以得出 但是多个圆 ...

  8. 【BZOJ1043】[HAOI2008]下落的圆盘 几何

    [BZOJ1043][HAOI2008]下落的圆盘 Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求.  ...

  9. 洛谷 P4290 [HAOI2008]玩具取名

    传送门 思路 博客半年没更新了,来更新个博文吧 在\(dsr\)聚聚博客的帮助下,我用半个上午和一个中午的时间苟延残喘地完成了这道题 先是读题目读大半天,最后连个样例都看不懂 之后又是想思路,实在想不 ...

随机推荐

  1. java常见的几种调用机制(同步调用,异步调用,回调)

    1.同步调用 同步调用是最基本的调用方式,对象b中的方法直接调用对象a的方法,这个时候程序会等待对象a的方法执行完返回结果之后才会继续往下走. 代码如下: public class A {public ...

  2. 如何查看apache加载了哪些模块

    apache2/bin/apachectl -l 可以看到类似下面的结果: 这是编译时就已编译在apache中的模块,启动时自然会加载. 另外一部分,要看apach的配置文件(httpd.conf)的 ...

  3. 数据分析工具pandas简介

    什么是Pandas? Pandas的名称来自于面板数据(panel data)和Python数据分析(data analysis). Pandas是一个强大的分析结构化数据的工具集,基于NumPy构建 ...

  4. Windows 环境下Java调用CRF++详解

    1.步骤一览 2.步骤详情 2.1.环境准备 Swig(Simplified Wrapper and Interface Generator)下载,Windows操作系统直接解压即可使用 CRF++( ...

  5. CImage得到位图的大小

    CImage image; image.Load(_T("1.jpg")); //HBITMAP hBitmap=image.Detach(); HGLOBAL m_hMem = ...

  6. 一些c++

    1.static 静态局部对象: 一旦被创建,在程序结束前都不会被撤销.当定义静态局部对象的函数结束时,静态局部对象不会撤销. 2.内联函数: 避免函数调用的开销. 在函数返回类型前加上关键字 inl ...

  7. codeforce 457DIV2 B题

    题意:  题目给出两个整数n,k,(n<=10^18,k<=10^5),求一个含有k个整数的序列,要求以2为底,以序列内数字为幂的和为n,其中序列内最大的数最小,若有多个序列满足条件,输出 ...

  8. Gym 101128A :Promotions (Southwestern Europe Regional Contest )

    题意 一个公司里有E个员工P个上下级关系.这个公司有一种晋升制度.如果要晋升员工a,那么必须要先晋升a的所有领导.给出一个区间[A,B],如果要晋升A个员工,有哪些员工是一定会被晋升的?如果要晋升B个 ...

  9. 扩展卡尔曼滤波EKF与多传感器融合

    参考:https://blog.csdn.net/young_gy/article/details/78468153 Extended Kalman Filter(扩展卡尔曼滤波)是卡尔曼滤波的非线性 ...

  10. 在Sqlserver中使用Try Catch

      创建错误日志表: CREATE TABLE ErrorLog(errNum INT,ErrSev NVARCHAR(1000),ErrState INT,ErrProc NVARCHAR(1000 ...