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

1043: [HAOI2008]下落的圆盘

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1598  Solved: 676
[Submit][Status][Discuss]

Description

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

Input

  第一行为1个整数n,N<=1000
接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标.

Output

  最后的周长,保留三位小数

Sample Input

2
1 0 0
1 1 0

Sample Output

10.472

HINT

Source

可以考虑后放的盘子对先放的盘子造成的覆盖影响
枚举每个盘,这个盘贡献的答案就是它的周长减去被后面的盘所覆盖的部分
圆和圆相交部分长度可以转化成线段覆盖问题来计算:算出中轴线的角度x,再计算圆心到2交点的角度y,

圆上被覆盖的弧度区间就是[x-y,x+y]
几个圆与这个圆相交,把相交覆盖的弧转化成圆上的线段,做一个线段覆盖问题就可以解决

 1 #include<bits/stdc++.h>
 2 #define reg register
 3 #define N 1005
 4 using namespace std;
 5 int n,tp;double x[N],y[N],r[N],ans;const double pi=acos(-1);struct node{double l,r;}q[N<<1];
 6 double dis(int i,int j){return sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));}
 7 bool con(int i,int j){return r[i]>=r[j]+dis(i,j);}
 8 bool cmp(node a,node b){return a.l<b.l;}
 9 void push(int i,int j){
10     double d,k,t,mv;
11     d=dis(i,j);k=atan2(y[j]-y[i],x[j]-x[i]);
12     t=(d*d+r[i]*r[i]-r[j]*r[j])/2/d;
13     mv=acos(t/r[i]);
14     q[++tp]=(node){k-mv,k+mv};
15 }
16 double calc(int p){
17     tp=0;
18     for(reg int i=p+1;i<=n;i++)
19     if(con(i,p))return 0;
20     for(int i=p+1;i<=n;i++){
21         if(con(p,i)||dis(i,p)>r[i]+r[p])continue;
22         push(p,i);
23     }
24     for(reg int i=1;i<=tp;i++){
25         if(q[i].l<0)q[i].l+=2*pi;
26         if(q[i].r<0)q[i].r+=2*pi;
27         if(q[i].l>q[i].r){
28             q[++tp]=(node){0,q[i].r};
29             q[i].r=2*pi;
30         }
31     }
32     sort(q+1,q+1+tp,cmp);
33     double cov=0,mx=q[1].l;
34     for(reg int i=1;i<=tp;i++){
35         mx=max(mx,q[i].l);
36         if(q[i].r<=mx)continue;
37         cov+=q[i].r-mx;mx=q[i].r;
38     }
39     double ret=r[p]*(2*pi-cov);
40     return ret;
41 }
42
43 int main(){
44     scanf("%d",&n);
45     for(reg int i=1;i<=n;i++)
46     scanf("%lf%lf%lf",&r[i],&x[i],&y[i]);
47     for(reg int i=1;i<=n;i++)ans+=calc(i);
48     printf("%.3lf\n",ans);
49     return 0;
50 }

原文地址:https://www.cnblogs.com/wsy01/p/8178841.html

时间: 2025-01-14 15:19:38

bzoj1043[HAOI2008]下落的圆盘 计算几何的相关文章

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

题目描述 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求. 输入 第一行为1个整数n,N<=1000接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标. 输出 最后的周长,保留三位小数 样例输入 2 1 0 0 1 1 0 样例输出 10.472 题解 计算几何 考虑从下到上的每一个圆,它被其它的圆覆盖了多少.即考虑它被覆盖了多少弧度. 考虑两个圆,如果相离则不覆盖,内含判断一下包含关系. 如果

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

题目大意:n个圆盘依次下落.求终于能看到的轮廓线面积 円盘反对! 让我们一起团结起来! 赶走円盘! 咳咳.非常神的一道题 今天去看了题解和白书才搞出来-- 首先我们倒着做 对于每一个圆盘处理出在它之后落下的圆盘和它的覆盖区间 然后求一个区间并就能算出这个圆盘的可见弧长 然后就是相交部分怎么求的问题了 首先两个圆必须相交 然后作圆心1到圆心2的向量 用atan2求出极角 然后利用余弦定理求出两个交点和圆心连线的夹角就可以 注意区间不在[0,2π]的部分要切割成还有一个区间 处理起来事实上不是非常麻

BZOJ1043 [HAOI2008]下落的圆盘

倒过来做,然后就变成了线段覆盖问题了. 线段覆盖就是贪心即可... 但是好烦好烦= =,需要耐心和几何基础2333 1 /************************************************************** 2 Problem: 1043 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:240 ms 7 Memory:872 kb 8 ****************************

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

http://172.20.6.3/Problem_Show.asp?id=1502这种题用了快一天才写出来也是真的辣鸡.主要思路就是计算一下被挡住的弧度然后对弧度进行贪心.最开始比较困扰的是求弧度值及其起始位置的部分,弧度值很好求,位置有点恶心,我的起始位置设置的是圆的十二点方向顺时针到起始位置的弧度值,然后我分了四种情况讨论(因为遮挡的方向有两种不同情况,遮挡部分弧度值与180度的关系又是两种情况),应该是有更简单的方法的,但是我只能想出来这种了... 代码 1 #include<cstdi

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

[BZOJ1043][HAOI2008]下落的圆盘 Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红色线条的总长度即为所求.  Input 第一行为1个整数n,N<=1000接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标. Output 最后的周长,保留三位小数 Sample Input 2 1 0 0 1 1 0 Sample Output 10.472 题解:对于每个圆,我们枚举它后面的

【BZOJ1043】【HAOI2008】下落的圆盘 计算几何

链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/46564199"); } 题解: 给每个圆求一下: 1. 它是不是被之后的某圆整体覆盖. 2. 它的圆周上有哪些弧段被覆盖了. 然后对于每个圆求一下还剩多少周长即可. 上述的"2."可以用圆的圆心角

BZOJ1043:[HAOI2008]下落的圆盘——题解

http://www.lydsy.com/JudgeOnline/problem.php?id=1043 Description 有n个圆盘从天而降,后面落下的可以盖住前面的.求最后形成的封闭区域的周长.看下面这副图, 所有的红 色线条的总长度即为所求. Input 第一行为1个整数n,N<=1000 接下来n行每行3个实数,ri,xi,yi,表示下落时第i个圆盘的半径和圆心坐标. Output 最后的周长,保留三位小数 Sample Input 2 1 0 0 1 1 0 Sample Out

【BZOJ】1043: [HAOI2008]下落的圆盘(计算几何+贪心)

http://www.lydsy.com/JudgeOnline/problem.php?id=1043 唯一让我不会的就是怎么求圆的周长并QAAQ... 然后发现好神!我们可以将圆弧变成$[0, 2 \pi ]$的直线! 然后一定要注意!起点是$(1, 0)$(单位圆) 首先学了余弦定理... 在三角形ABC中 $$cos A=\frac{|AB|^2+|AC|^2-|BC|^2}{2|AB| |AC|}$$ 证明很简单... $$\begin{align}|{BC}|^2 & = \vec{

BZOJ 1043: [HAOI2008]下落的圆盘

Description 求几个圆交起来的周长..\(n\leqslant 10^3\) Solution 计算几何. 圆圆求交.. Code /************************************************************** Problem: 1043 User: BeiYu Language: C++ Result: Accepted Time:520 ms Memory:1308 kb *******************************