下落的圆盘

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

Description

  有n个圆盘从天而降,后面落下的可以盖住前面的。求最后形成的封闭区域的周长。

  看下面这副图, 所有的红色线条的总长度即为所求。

  

Input

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

Output

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

Sample Input

  2
  1 0 0
  1 1 0

Sample Output

  10.472

HINT

  n <= 1000

Solution

  显然是一道计算几何题。

  考虑一个圆对于答案的贡献,显然是这个圆的周长 - 后面的圆把它覆盖掉的周长的并。那么我们就考虑怎么求这个并。

  先考虑怎样记录下一个答案,显然直接扣掉单个圆对它的覆盖不可行的,要减去重叠的情况

  既然边不可行,我们就用角度。显然,若我们求出 两圆交点的角度 即可解决这题。

  我们考虑求圆A被圆B覆盖的角度:现在我们有两个圆的半径、圆心距。我们就可以得到 圆A与圆B圆心连线圆A半径 的夹角。

  我们也可以知道 圆A与圆B圆心连线x轴的夹角

  这样的话,就可以把单个圆对于它的贡献记录到栈里面,最后扫一遍求一下剩余的角度乘上R就是它对于答案的贡献了。

Code

 1 #include<iostream>
 2 #include<string>
 3 #include<algorithm>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cmath>
 8 #include<queue>
 9 using namespace std;
10 typedef unsigned long long s64;
11
12 const int ONE = 1000005;
13 const double pi = acos(-1.0);
14
15 int n;
16 struct power
17 {
18         double x, y, r;
19 }a[ONE];
20
21 struct circle
22 {
23         double a, b;
24 }stk[ONE];
25 int top;
26
27 double Ans;
28
29 bool cmp(const circle &a, const circle &b)
30 {
31         if(a.a != b.a) return a.a < b.a;
32         return a.b < b.b;
33 }
34
35 int get()
36 {
37         int res,Q=1;    char c;
38         while( (c=getchar())<48 || c>57)
39         if(c=='-')Q=-1;
40         if(Q) res=c-48;
41         while((c=getchar())>=48 && c<=57)
42         res=res*10+c-48;
43         return res*Q;
44 }
45
46 double sqr(double x) {return x * x;}
47 double dist(power a, power b) {return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));}
48
49 double Calc(power a, power b)
50 {
51         double A = a.r, B = b.r, C = dist(a, b);
52         double cosB = (sqr(A) + sqr(C) - sqr(B)) / (2 * A * C);
53         double angle = atan2(a.x - b.x, a.y - b.y), add = acos(cosB);
54         stk[++top] = (circle){angle - add, angle + add};
55 }
56
57 double init(power a, power b) {return a.r + dist(a, b) <= b.r;}
58 double sect(power a, power b) {return fabs(a.r - b.r) < dist(a, b) && dist(a, b) < a.r + b.r;}
59
60 double Deal(int id)
61 {
62         top = 0;
63         for(int i = id+1; i <= n; i++)
64             if(init(a[id], a[i])) return 0;
65
66         for(int i = id+1; i <= n; i++)
67             if(sect(a[id], a[i])) Calc(a[id], a[i]);
68
69         for(int i = 1; i <= top; i++)
70         {
71             while(stk[i].a < 0) stk[i].a += 2 * pi;
72             while(stk[i].b < 0) stk[i].b += 2 * pi;
73             if(stk[i].a > stk[i].b) stk[++top] = (circle){0, stk[i].b}, stk[i].b = 2*pi;
74         }
75
76         sort(stk + 1, stk + top + 1, cmp);
77         double last = 0.0, sum = 0.0;
78         for(int i = 1; i <= top; i++)
79             if(stk[i].a > last) sum += stk[i].a - last, last = stk[i].b;
80             else last = max(last, stk[i].b);
81
82         sum += 2 * pi - last;
83         return a[id].r * sum;
84 }
85
86 int main()
87 {
88         n = get();
89         for(int i = 1; i <= n; i++)
90             scanf("%lf %lf %lf", &a[i].r, &a[i].x, &a[i].y);
91         for(int i = 1; i <= n; i++)
92             Ans += Deal(i);
93         printf("%.3lf", Ans);
94 }

View Code

转载于:https://www.cnblogs.com/BearChild/p/7280763.html

【BZOJ1043】下落的圆盘 [计算几何]相关推荐

  1. [暑假的bzoj刷水记录]

    (这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊  堆一起算了 隔一段更新一下.  7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...

  2. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

  3. 重走长征路---OI每周刷题记录---12月6日 2014

    总目录详见https://blog.csdn.net/mrcrack/article/details/84471041 做题原则,找不到测评地址的题不做.2018-11-28 重走长征路---OI每周 ...

  4. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

  5. 【计算几何】Delaunay 三角剖分原理与实现

    摘 要: 平面点集的三角剖分在数值分析以及图形领域,都是极为重要的一项预处理技术.作为一种广泛应用的三角剖分技术,Delaunay三角剖分通过最大化最小角确保接近与规则的三角网和唯一性.本文通过概述 ...

  6. PIXI 下落文字消除(3)

    图片示例,简陋的图,记录下落过程, 1.创建应用实例并添加到DOM元素上. (会看到一个黑色画布,没有任何元素,接下来会在画布上创建文字) 2.创建  TextStyle 用来设置要显示字体样式 3. ...

  7. AcWing 2984. 线段 / POJ3304(计算几何、常用技巧转换)

    常用技巧转换,寻找一个直线旋转 我们发现如果可以找到一个直线与所有的线段都相交,那么我们做一个垂直这个直线的垂线,所有的线段的投影一定都交于这个直线与垂线的垂足处,我们可以很轻松地画图验证这一定理. ...

  8. 模板 -计算几何注意事项

    整理的算法模板合集: ACM模板 目录 计算误差 解决方案 : 误差判别法 解决方案:化浮为整 注意负零 注意反三角函数的值域 计算几何常用开头模板 在写计算几何的题目的时候一般习惯数组从0开始(至少 ...

  9. 二维几何基础大合集!《计算几何全家桶(一)》(基础运算、点、线、多边形、圆、网格)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的模板整合计划 目录 1.基本运算 1.1 判断正负函数(sgn) 1.2 点积(数量积.内积)(Dot) 1.3 向量积 ...

最新文章

  1. html动态加载js方法,如何通过JavaScript动态加载js
  2. Python zipfile 压缩文件夹
  3. Example of ConcurrentHashMap in Java--转
  4. Oracle单机报监听不支持服务,(转)oracle 启动监听 报“监听程序不支持服务” 解决...
  5. Eclipse 插件开发遇到问题心得总结
  6. 是时候好好去学门脚本语言了
  7. as 插件GsonFormat用法(json字符串快速生成javabean)
  8. 算法(三)、[海量] 数据处理
  9. Flutter之跨组件状态共享Provider框架剖析(2)
  10. [学习笔记]java基础Java8SE开发环境搭建、第一个Java Hello World、Java程序的编译与执行...
  11. 微信朋友圈 腾讯服务器,朋友圈@微信能得一面红旗?腾讯服务器一度宕机
  12. 分数化简通分:最大公约数与最小公倍数
  13. 华为无线网卡无服务器,联通华为无线上网卡连接时连接被终止解决方法 - 小众知识...
  14. 微信公众号授权登录(asp.net + angular)
  15. IrisSkin 皮肤
  16. 台湾大学教授洪士灏对产业前景的讨论
  17. ChatGPT会对未来5年的NLP算法从业者带来怎样的冲击?
  18. Win10系统还原文件默认打开方式
  19. .NET Core Onvif协议C#教程系列之XiaoFeng.Onvif组件库
  20. android studio 皮肤,Android Studio 自定义皮肤主题和背景

热门文章

  1. [cocos2d-x][apk打包][Fatal signal 11][andriod]Eclipse编译Fatal signal 11报错-都是字符赋值惹的祸...
  2. java字节码忍者禁术
  3. linux C 快速排序法
  4. OSPF的LSA类型 ——连载五自治系统外部的LSA
  5. 【2010福建】收稻子 (校BSOJ1114)
  6. POJ 3687 Labeling Balls
  7. 20190421-那些年使用过的CSS预处理器(CSS Preprocessor)之Sass and Less
  8. Java 整数型的进制间的互相转换
  9. 记linux_centOS安装as86过程
  10. 刪數 (Standard IO)