P2510 [HAOI2008]下落的圆盘
首先考虑两个圆覆盖的情况,我们可以求出圆心与交点连线 $A$ 的极角
具体就是求出两圆心连线 $B$ 极角加上余弦定理加反余弦求出 $A,B$ 之间夹角 ,然后覆盖了多少就可以得出
但是多个圆覆盖会重复算,所以离线枚举后面的圆,然后把覆盖的区间按极角排序做一遍类似线段覆盖的操作就行了
区间覆盖的时候注意极角可以会算出负数和大于 $2\pi$ 的情况
思路倒挺简单,计算几何实现起来反正就是一堆细节
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
typedef double db;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const db pi=acos(-1.0),pi2=pi*,eps=1e-;
const int N=;
int n;
inline int dcmp(db x) { if(fabs(x)<eps) return ; return x< ? - : ; }
struct Poi {
db x,y;
Poi (db a=,db b=) { x=a,y=b; }
inline Poi operator - (const Poi &tmp) const {
return Poi(x-tmp.x,y-tmp.y);
}
};
inline db Len(Poi A) { return sqrt(A.x*A.x+A.y*A.y); }
inline db angle(Poi A) { return atan2(A.y,A.x); }
struct Circ {
Poi O; db r;
Circ (Poi a=Poi(,),db b=) { O=a,r=b; }
}C[N];
struct dat {
db ang; int type;
dat (db a=,int b=) { ang=a,type=b; }
inline bool operator < (const dat &tmp) const {
return ang<tmp.ang;
}
}D[N];
db work(int p)
{
db res=; int tot=,cnt=;
for(int i=p+;i<=n;i++)
{
db dis=Len(C[i].O-C[p].O);
if( C[p].r+dis<=C[i].r ) return ;//p被完全覆盖
if( dis>=C[p].r+C[i].r || C[i].r+dis<=C[p].r ) continue;//p没被覆盖,记得可能 i 在 p 里面
db alp=acos( (dis*dis+C[p].r*C[p].r-C[i].r*C[i].r)/(*dis*C[p].r) ),k=angle(C[i].O-C[p].O);
db l=k-alp,r=k+alp;//两个交点的极角
if(dcmp(l)<&&dcmp(r)<) { D[++tot]=dat(l+pi2,); D[++tot]=dat(r+pi2,-); continue; }
if(dcmp(l)>=&&r<=pi2) { D[++tot]=dat(l,); D[++tot]=dat(r,-); continue; }
if(dcmp(l)<&&dcmp(r)>=)
{
D[++tot]=dat(l+pi2,); D[++tot]=dat(pi2,-);
D[++tot]=dat(,); D[++tot]=dat(r,-);
}
if(dcmp(l)>=&&r>pi2)
{
D[++tot]=dat(,); D[++tot]=dat(r-pi2,-);
D[++tot]=dat(l,); D[++tot]=dat(pi2,-);
}
}
sort(D+,D+tot+);
for(int i=;i<=tot;i++)
{
if(D[i].type==&&!cnt) res+=D[i].ang-D[i-].ang;//线段覆盖
cnt+=D[i].type;
}
res+=pi2-D[tot].ang;
return C[p].r*res;
}
int main()
{
n=read(); db a,b,c,ans=;
for(int i=;i<=n;i++)
{
scanf("%lf%lf%lf",&a,&b,&c);
C[i]=Circ( Poi(b,c) , a );
}
for(int i=;i<=n;i++) ans+=work(i);
printf("%.3f\n",ans);
return ;
}
P2510 [HAOI2008]下落的圆盘的更多相关文章
- luogu P2510 [HAOI2008]下落的圆盘
LINK:下落的圆盘 计算几何.n个圆在平面上编号大的圆将编号小的圆覆盖求最后所有没有被覆盖的圆的边缘的总长度. 在做这道题之前有几个前置知识. 极坐标系:在平面内 由极点 极轴 和 极径组成的坐标系 ...
- 洛谷P2510 [HAOI2008]下落的圆盘(计算几何)
题面 传送门 题解 对于每个圆,我们单独计算它被覆盖的周长是多少 只有相交的情况需要考虑,我们需要知道相交的那段圆弧的角度,发现其中一个交点和两个圆的圆心可以构成一个三角形且三边都已经知道了,那么我们 ...
- bzoj1043[HAOI2008]下落的圆盘 计算几何
1043: [HAOI2008]下落的圆盘 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1598 Solved: 676[Submit][Stat ...
- 【BZOJ1043】[HAOI2008]下落的圆盘 几何
[BZOJ1043][HAOI2008]下落的圆盘 Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. ...
- BZOJ 1043 HAOI2008 下落的圆盘 计算几何
题目大意:n个圆盘依次下落.求终于能看到的轮廓线面积 円盘反对! 让我们一起团结起来! 赶走円盘! 咳咳.非常神的一道题 今天去看了题解和白书才搞出来-- 首先我们倒着做 对于每一个圆盘处理出在它之后 ...
- [HAOI2008]下落的圆盘
Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红 色线条的总长度即为所求. Input 第一行为1个整数n,N<=100 ...
- bzoj1043 [HAOI2008]下落的圆盘
Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. Input 第一行为1个整数n,N<=1000 ...
- BZOJ1043:[HAOI2008]下落的圆盘——题解(配图片)
http://www.lydsy.com/JudgeOnline/problem.php?id=1043 Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周 ...
- Bzoj1313 [HAOI2008]下落的圆盘
有 n 个圆盘从天而降,后面落下的可以盖住前面的.最后按掉下的顺序,在平面上依次测得每个圆盘的圆心和半径,问下落完成后从上往下看,整个图形的周长是多少,即你可以看到的圆盘的轮廓的圆盘的轮廓总长.例如下 ...
随机推荐
- PHP基础教程探讨一些php编程性能优化总结
兄弟连PHP培训 小编最近在做php程序的性能优化,一些经过测试后发现的东西就先记录下来,以备后用. 首先对于一些反应慢的操作或页面要跟踪处理一下,可以使用webGrind的方式看一下主要问题出在 ...
- 3D Computer Grapihcs Using OpenGL - 17 添加相机(旋转)
在11节我们说过,MVP矩阵中目前只应用了两个矩阵,World to View 矩阵被省略了,这就导致我们的画面没有办法转换视角. 本节我们将添加这一环节,让相机可以旋转. 为了实现这一目的,我们添加 ...
- HDU1847--Good Luck in CET-4 Everybody!(SG函数)
Problem Description 大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的ACM都没工夫练习了,反正我知道的Kiki和Cici都是如此.当然,作为在考场浸润了十几载 ...
- java中Thread (线程)
Thread 使用新线程的步骤: 通过覆写 Thread 的 run 方法,配置新线程需要做的事情 创建新线程对象 new YourThread() 开启线程 start 创建新线程的方法有很多,下面 ...
- ubuntu16虚拟机迁移/移动/复制后无法上网
修改grub配置 如果没有网卡,需要配置 sudo vi /etc/default/grub 将 GRUB_CMDLINE_LINUX="" 修改为 GRUB_CMDLINE_LI ...
- 一、基础篇--1.1Java基础-重载和重写的区别
重载和重写的区别 重写: 1.也叫子类的方法覆盖父类的方法,要求返回值.方法名和参数都相同: 2.子类抛出的异常不能超过父类相应方法抛出的异常.(子类异常不能超出父类异常): 3.子类方法的的访问级别 ...
- IDEA 中常用快捷键的使用
IDEA 中快捷键的使用 1:知道类名全局查找类: Ctrl+Shift+Alt+N; 全局搜索: Ctrl+Shift+R 2:快速定位到类的文件夹: 3: 优化导入的类和包 (删除 ...
- windows程序调试
由于不能在控制台输出,可以使用Messagebox 但是有时候要用到输出int之类的,需要转换.转换过程中有会有很多问题. 这里给出两个可行的代码 int a = 5, b = 10; int res ...
- 存取code 操作内容
笔记! 实现: 前端: 首先导航需要给他们code(主键): <foreach name="chaa" item="ab"> <if cond ...
- 使用Callable或DeferredResult实现springmvc的异步请求
使用Callable实现springmvc的异步请求 如果一个请求中的某些操作耗时很长,会一直占用线程.这样的请求多了,可能造成线程池被占满,新请求无法执行的情况.这时,可以考虑使用异步请求,即主线程 ...