题意:求 m 个圆的并的面积。

析:就是一个板子题,还有要注意圆的半径为0的情况。

代码如下:

  1. #pragma comment(linker, "/STACK:1024000000,1024000000")
  2. #include <cstdio>
  3. #include <string>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <iostream>
  7. #include <cstring>
  8. #include <set>
  9. #include <queue>
  10. #include <algorithm>
  11. #include <vector>
  12. #include <map>
  13. #include <cctype>
  14. #include <cmath>
  15. #include <stack>
  16. #include <sstream>
  17. #define debug() puts("++++");
  18. #define gcd(a, b) __gcd(a, b)
  19. #define lson l,m,rt<<1
  20. #define rson m+1,r,rt<<1|1
  21. #define freopenr freopen("in.txt", "r", stdin)
  22. #define freopenw freopen("out.txt", "w", stdout)
  23. using namespace std;
  24.  
  25. typedef long long LL;
  26. typedef unsigned long long ULL;
  27. typedef pair<double, int> P;
  28. const int INF = 0x3f3f3f3f;
  29. const double inf = 0x3f3f3f3f3f3f;
  30. const double PI = acos(-1.0);
  31. const double eps = 1e-8;
  32. const int maxn = 1e4 + 10;
  33. const int mod = 1e6;
  34. const int dr[] = {-1, 0, 1, 0};
  35. const int dc[] = {0, 1, 0, -1};
  36. const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
  37. int n, m;
  38. const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  39. const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  40. inline bool is_in(int r, int c){
  41. return r >= 0 && r < n && c >= 0 && c < m;
  42. }
  43.  
  44. int dcmp(double x){
  45. if(fabs(x) < eps) return 0;
  46. if(x > 0) return 1;
  47. return -1;
  48. }
  49. double sqr(double x){ return x * x; }
  50.  
  51. struct Point{
  52. double x, y;
  53. Point(){ }
  54. Point(double a, double b) : x(a), y(b) { }
  55. void input(){
  56. scanf("%lf %lf", &x, &y);
  57. }
  58. friend Point operator + (const Point &a, const Point &b){
  59. return Point(a.x + b.x, a.y + b.y);
  60. }
  61. friend Point operator - (const Point &a, const Point &b){
  62. return Point(a.x - b.x, a.y - b.y);
  63. }
  64. friend bool operator == (const Point &a, const Point &b){
  65. return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
  66. }
  67. friend Point operator * (const Point &a, const double &b){
  68. return Point(a.x * b, a.y * b);
  69. }
  70. friend Point operator * (const double &b, const Point &a){
  71. return Point(a.x * b, a.y * b);
  72. }
  73. friend Point operator / (const Point &a, const double &b){
  74. return Point(a.x / b, a.y / b);
  75. }
  76. double norm(){
  77. return sqrt(sqr(x) + sqr(y));
  78. }
  79. };
  80. double cross(const Point &a, const Point &b){
  81. return a.x * b.y - a.y * b.x;
  82. }
  83. struct Circle{
  84. Point p;
  85. double r;
  86. bool operator < (const Circle &o) const{
  87. if(dcmp(r-o.r) != 0) return dcmp(r-o.r) == -1;
  88. if(dcmp(p.x-o.p.x) != 0) return dcmp(p.x - o.p.x) == -1;
  89. return dcmp(p.y - o.p.y) == -1;
  90. }
  91. bool operator == (const Circle &o) const{
  92. return dcmp(r - o.r) == 0 && dcmp(p.x - o.p.x) == 0 && dcmp(p.y - o.p.y) == 0;
  93. }
  94. };
  95. Point rotate(const Point &p, double cost, double sint){
  96. double x = p.x, y = p.y;
  97. return Point(x*cost - y*sint, x*sint + y*cost);
  98. }
  99.  
  100. pair<Point, Point> crossPoint(Point ap, double ar, Point bp, double br){
  101. double d = (ap - bp).norm();
  102. double cost = (ar*ar + d*d - br*br) / (2.0*ar*d);
  103. double sint = sqrt(1.0 - cost*cost);
  104. Point v = (bp - ap) / (bp - ap).norm() * ar;
  105. return make_pair(ap+rotate(v, cost, -sint), ap+rotate(v, cost, sint));
  106. }
  107.  
  108. pair<Point, Point> crossPoint(const Circle &a, const Circle &b){
  109. return crossPoint(a.p, a.r, b.p, b.r);
  110. }
  111. Circle c[maxn], tc[maxn];
  112. #include<complex>
  113. struct Node{
  114. Point p;
  115. double a;
  116. int d;
  117. Node(const Point &pp, double aa, int dd) : p(pp), a(aa), d(dd) { }
  118. bool operator < (const Node &o) const{
  119. return a < o.a;
  120. }
  121. };
  122. double arg(Point p){
  123. return arg(complex<double> (p.x, p.y));
  124. }
  125.  
  126. double solve(){
  127. sort(tc, tc + m);
  128. m = unique(tc, tc + m) - tc;
  129. n = 0;
  130. for(int i = m-1; i >= 0; --i){
  131. bool ok = true;
  132. for(int j = i+1; j < m; ++j){
  133. double d = (tc[i].p - tc[j].p).norm();
  134. if(dcmp(d - abs(tc[i].r - tc[j].r)) <= 0){
  135. ok = false; break;
  136. }
  137. }
  138. if(ok) c[n++] = tc[i];
  139. }
  140. double ans = 0.0;
  141. for(int i = 0; i < n; ++i){
  142. vector<Node> event;
  143. Point boundary = c[i].p + Point(-c[i].r, 0);
  144. event.push_back(Node(boundary, -PI, 0));
  145. event.push_back(Node(boundary, PI, 0));
  146. for(int j = 0; j < n; ++j){
  147. if(i == j) continue;
  148. double d = (c[i].p - c[j].p).norm();
  149. if(dcmp(d - (c[i].r + c[j].r)) < 0){
  150. pair<Point, Point> ret = crossPoint(c[i], c[j]);
  151. double x = arg(ret.first - c[i].p);
  152. double y = arg(ret.second - c[i].p);
  153. if(dcmp(x - y) > 0){
  154. event.push_back(Node(ret.first, x, 1));
  155. event.push_back(Node(boundary, PI, -1));
  156. event.push_back(Node(boundary, -PI, 1));
  157. event.push_back(Node(ret.second, y, -1));
  158. }
  159. else{
  160. event.push_back(Node(ret.first, x, 1));
  161. event.push_back(Node(ret.second, y, -1));
  162. }
  163. }
  164. }
  165. sort(event.begin(), event.end());
  166. int sum = event[0].d;
  167. for(int j = 1; j < event.size(); ++j){
  168. if(sum == 0){
  169. ans += cross(event[j-1].p, event[j].p) / 2.0;
  170. double x = event[j-1].a;
  171. double y = event[j].a;
  172. double area = c[i].r * c[i].r * (y-x) / 2.0;
  173. Point v1 = event[j-1].p - c[i].p;
  174. Point v2 = event[j].p - c[i].p;
  175. area -= cross(v1, v2) / 2.0;
  176. ans += area;
  177. }
  178. sum += event[j].d;
  179. }
  180. }
  181. return ans;
  182. }
  183.  
  184. int main(){
  185. while(scanf("%d", &n) == 1){
  186. m = 0;
  187. for(int i = 0; i < n; ++i){
  188. tc[m].p.input();
  189. scanf("%lf", &tc[m].r);
  190. if(dcmp(tc[m].r) <= 0) continue;
  191. ++m;
  192. }
  193. printf("%.3f\n", solve());
  194. }
  195. return 0;
  196. }

SPOJ CIRU The area of the union of circles (计算几何)的更多相关文章

  1. SPOJ CIRU - The area of the union of circles (圆的面积并)

    CIRU - The area of the union of circles no tags  You are given N circles and expected to calculate t ...

  2. SPOJ CIRU The area of the union of circles

    You are given N circles and expected to calculate the area of the union of the circles ! Input The f ...

  3. SPOJ CIRU The area of the union of circles ——Simpson积分

    [题目分析] 圆的面积并. 直接Simpson积分,(但是有计算几何的解法,留着flag). simpson积分,如果圆出现了不连续的情况,是很容易出事情的.(脑补一下) 但是没有什么办法,本来就是一 ...

  4. 【题解】CIRU - The area of the union of circles [SP8073] \ 圆的面积并 [Bzoj2178]

    [题解]CIRU - The area of the union of circles [SP8073] \ 圆的面积并 [Bzoj2178] 传送门: \(\text{CIRU - The area ...

  5. SPOJ 8073 The area of the union of circles(计算几何の圆并)(CIRU)

    Description You are given N circles and expected to calculate the area of the union of the circles ! ...

  6. SPOJ 8073 The area of the union of circles (圆并入门)

    Sphere Online Judge (SPOJ) - Problem CIRU [求圆并的若干种算法,圆并扩展算法]_AekdyCoin的空间_百度空间 参考AekdyCoin的圆并算法解释,根据 ...

  7. [SPOJ-CIRU]The area of the union of circles/[BZOJ2178]圆的面积并

    [SPOJ-CIRU]The area of the union of circles/[BZOJ2178]圆的面积并 题目大意: 求\(n(n\le1000)\)个圆的面积并. 思路: 对于一个\( ...

  8. SPOJ CIRU SPOJ VCIRCLE 圆的面积并问题

    SPOJ VCIRCLE SPOJ CIRU 两道题都是给出若干圆 就面积并,数据规模和精度要求不同. 求圆面积并有两种常见的方法,一种是Simpson积分,另一种是几何法. 在这里给出几何方法. P ...

  9. SPOJ CIRU

    SPOJ CIRU 题意 给出n个圆,求他们覆盖的面积. 解法 自适应Simpson,但需要将圆离散化一下,以保证我们查询的是一个连续的有圆的区间. 奇怪的是我没有离散化,样例都没有过,却把题给A了 ...

随机推荐

  1. JS 常用字符串操作

    Js字符串操作函数大全 /*******************************************                        字符串函数扩充              ...

  2. Carriage-Return Line-Feed

    Git 提交时报错warning: LF will be replaced by CRLF in - CSDN博客 https://blog.csdn.net/yan_less/article/det ...

  3. mongodb学习之:安全和认证

    mongodb默认是不认证的,默认没有账号,只要能连接上服务就可以对数据库进行各种操作,mongodb认为安全最好的方法就是在一个可信的环境中运行它,保证之后可信的机器才能访问它.因此需要在登录的时候 ...

  4. Machine Learning in Action(6) AdaBoost算法

    Adaboost也是一种原理简单,但很实用的有监督机器学习算法,它是daptive boosting的简称.说到boosting算法,就不得提一提bagging算法,他们两个都是把一些弱分类器组合起来 ...

  5. codeforces Codeforces Round #273 (Div. 2) 478B

    B. Random Teams time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...

  6. UVA10129 Play on Words —— 欧拉回路

    题目链接:https://vjudge.net/problem/UVA-10129 代码如下: // UVa10129 Play on Words // Rujia Liu // 题意:输入n个单词, ...

  7. zabbix 中 宏 的介绍

    宏的作用是便于在模板.items.trigger中的引用.宏的名称为 {$名称},宏的字符范围为 A~Z.0~9._ . 例如: 在key中的宏: net.tcp.service[ssh,{$SSH_ ...

  8. rc.local 开启自启动,检测是否成功

    rc.local /etc/init.d/nginx start 查看运行状态 systemctl status rc-local ● rc-local.service - /etc/rc.local ...

  9. c#设置系统时间后不起作用

    网上设置系统时间的代码很多,但是会出现设置后没有作用的问题 遇到以上问题可以按照如下办法解决 1.项目--属性--安全性--勾选启用ClickOne安全设置,如下图所示: 2.打开app.manife ...

  10. hdu 2671 shǎ崽 OrOrOrOrz(排序)

    题意:排序后按题目要求输出 思路:排序 #include<iostream> #include<stdio.h> #include<algorithm> using ...