CIRU - The area of the union of circles

no tags 

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

Input

The first line is one integer n indicates the number of the circles. (1 <= n <= 1000)

Then follows n lines every line has three integers

Xi Yi Ri

indicates the coordinate of the center of the circle, and the radius. (|Xi|. |Yi|  <= 1000, Ri <= 1000)

Note that in this problem Ri may be 0 and it just means one point !

Output

The total area that these N circles with 3 digits after decimal point

Example

Input:
3
0 0 1
0 0 1
100 100 1 Output:
6.283
代码详解见 : http://www.cnblogs.com/oyking/p/3424999.html
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
typedef long long ll;
using namespace std;
const int N = 1e5+;
const int M = ;
const double PI = acos(-1.0);
const double EPS = 1e-; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} struct Point {
double x, y;
Point() {}
Point(double x, double y): x(x), y(y) {}
void read() {
scanf("%lf%lf", &x, &y);
}
double angle() {
return atan2(y, x);
}
Point operator + (const Point &rhs) const {
return Point(x + rhs.x, y + rhs.y);
}
Point operator - (const Point &rhs) const {
return Point(x - rhs.x, y - rhs.y);
}
Point operator * (double t) const {
return Point(x * t, y * t);
}
Point operator / (double t) const {
return Point(x / t, y / t);
}
double length() const {
return sqrt(x * x + y * y);
}
Point unit() const {
double l = length();
return Point(x / l, y / l);
}
}; double cross(const Point &a, const Point &b) {
return a.x * b.y - a.y * b.x;
} double dist(const Point &p1, const Point &p2) {
return (p1 - p2).length();
} Point rotate(const Point &p, double angle, const Point &o = Point(, )) {
Point t = p - o;
double x = t.x * cos(angle) - t.y * sin(angle);
double y = t.y * cos(angle) + t.x * sin(angle);
return Point(x, y) + o;
} struct Region {
double st, ed;
Region() {}
Region(double st, double ed): st(st), ed(ed) {}
bool operator < (const Region &rhs) const {
if(sgn(st - rhs.st)) return st < rhs.st;
return ed < rhs.ed;
}
}; struct Circle {
Point c;
double r;
vector<Region> reg;
Circle() {}
Circle(Point c, double r): c(c), r(r) {}
void read() {
c.read();
scanf("%lf", &r);
}
void add(const Region &r) {
reg.push_back(r);
}
bool contain(const Circle &cir) const {
return sgn(dist(cir.c, c) + cir.r - r) <= ;
}
bool intersect(const Circle &cir) const {
return sgn(dist(cir.c, c) - cir.r - r) < ;
}
}; double sqr(double x) {
return x * x;
} void intersection(const Circle &cir1, const Circle &cir2, Point &p1, Point &p2) {
double l = dist(cir1.c, cir2.c);
double d = (sqr(l) - sqr(cir2.r) + sqr(cir1.r)) / ( * l);
double d2 = sqrt(sqr(cir1.r) - sqr(d));
Point mid = cir1.c + (cir2.c - cir1.c).unit() * d;
Point v = rotate(cir2.c - cir1.c, PI / ).unit() * d2;
p1 = mid + v, p2 = mid - v;
} Point calc(const Circle &cir, double angle) {
Point p = Point(cir.c.x + cir.r, cir.c.y);
return rotate(p, angle, cir.c);
} const int MAXN = ; Circle cir[MAXN];
bool del[MAXN];
int n; double solve() {
double ans = ;
for(int i = ; i < n; ++i) {
for(int j = ; j < n; ++j) if(!del[j]) {
if(i == j) continue;
if(cir[j].contain(cir[i])) {
del[i] = true;
break;
}
}
}
for(int i = ; i < n; ++i) if(!del[i]) {
Circle &mc = cir[i];
Point p1, p2;
bool flag = false;
for(int j = ; j < n; ++j) if(!del[j]) {
if(i == j) continue;
if(!mc.intersect(cir[j])) continue;
flag = true;
intersection(mc, cir[j], p1, p2);
double rs = (p2 - mc.c).angle(), rt = (p1 - mc.c).angle();
if(sgn(rs) < ) rs += * PI;
if(sgn(rt) < ) rt += * PI;
if(sgn(rs - rt) > ) mc.add(Region(rs, PI * )), mc.add(Region(, rt));
else mc.add(Region(rs, rt));
}
if(!flag) {
ans += PI * sqr(mc.r);
continue;
}
sort(mc.reg.begin(), mc.reg.end());
int cnt = ;
for(int j = ; j < int(mc.reg.size()); ++j) {
if(sgn(mc.reg[cnt - ].ed - mc.reg[j].st) >= ) {
mc.reg[cnt - ].ed = max(mc.reg[cnt - ].ed, mc.reg[j].ed);
} else mc.reg[cnt++] = mc.reg[j];
}
mc.add(Region());
mc.reg[cnt] = mc.reg[];
for(int j = ; j < cnt; ++j) {
p1 = calc(mc, mc.reg[j].ed);
p2 = calc(mc, mc.reg[j + ].st);
ans += cross(p1, p2) / ;
double angle = mc.reg[j + ].st - mc.reg[j].ed;
if(sgn(angle) < ) angle += * PI;
ans += 0.5 * sqr(mc.r) * (angle - sin(angle));
}
}
return ans;
} int main() {
scanf("%d", &n);
for(int i = ; i < n; ++i) cir[i].read();
printf("%.3f\n", solve() + EPS);
}

SPOJ CIRU - The area of the union of circles (圆的面积并)的更多相关文章

  1. 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 ...

  2. SPOJ CIRU The area of the union of circles (计算几何)

    题意:求 m 个圆的并的面积. 析:就是一个板子题,还有要注意圆的半径为0的情况. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024 ...

  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. JavaScript(二):对象、注释、事件!

    对象 JavaScript的一个重要功能就是面向对象的功能,通过基于对象的程序设计,可以用更直观.模块化和可重复使用的方式进行程序开发. 一组包含数据的属性和对属性中包含数据进行操作的方法,称为对象. ...

  2. Notice : brew install php70

    To enable PHP in Apache add the following to httpd.conf and restart Apache: LoadModule php7_module  ...

  3. CF451E Devu and Flowers 解题报告

    CF451E Devu and Flowers 题意: \(Devu\)有\(N\)个盒子,第\(i\)个盒子中有\(c_i\)枝花.同一个盒子内的花颜色相同,不同盒子的花颜色不同.\(Devu\)要 ...

  4. BZOJ 3545 / 洛谷 P4197 Peaks 解题报告

    P4197 Peaks 题目描述 在\(\text{Bytemountains}\)有\(N\)座山峰,每座山峰有他的高度\(h_i\).有些山峰之间有双向道路相连,共\(M\)条路径,每条路径有一个 ...

  5. 理解[].forEach.call()

    例子: let cols = document.querySelectorAll('ul li') [].forEach.call(cols, function (col, index) { // T ...

  6. Codeforces Round #350 (Div. 2) D1

    D1. Magic Powder - 1 time limit per test 1 second memory limit per test 256 megabytes input standard ...

  7. Java拷贝构造函数初尝试

    浅复制(浅克隆) :被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. 深复制(深克隆) :被复制 ...

  8. 前端面试:什么是css reset

    HTML标签在浏览器中都有默认的样式,不同的浏览器的默认样式之间存在差别.例如ul默认带有缩进样式,在IE下,它的缩进是由margin实现的,而在Firefox下却是由padding实现的.开发时浏览 ...

  9. phpAdmin 修改密码后拒绝登陆

    phpMyadmin没配置正确,打开 phpMyadmin 目录找到config.inc.php文件,查找到$cfg['Servers'][$i]['password']='';这行,在''中输入你正 ...

  10. loj6030 「雅礼集训 2017 Day1」矩阵

    传送门:https://loj.ac/problem/6030 [题解] 以下把白称为0,黑称为1. 发现只有全空才是无解,否则考虑构造. 每一列,只要有0的格子都需要被赋值1次,所以设有x列有含有0 ...