SPOJ CIRU - The area of the union of circles (圆的面积并)
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 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 (圆的面积并)的更多相关文章
- 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 ...
- SPOJ CIRU The area of the union of circles (计算几何)
题意:求 m 个圆的并的面积. 析:就是一个板子题,还有要注意圆的半径为0的情况. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024 ...
- SPOJ CIRU The area of the union of circles ——Simpson积分
[题目分析] 圆的面积并. 直接Simpson积分,(但是有计算几何的解法,留着flag). simpson积分,如果圆出现了不连续的情况,是很容易出事情的.(脑补一下) 但是没有什么办法,本来就是一 ...
- 【题解】CIRU - The area of the union of circles [SP8073] \ 圆的面积并 [Bzoj2178]
[题解]CIRU - The area of the union of circles [SP8073] \ 圆的面积并 [Bzoj2178] 传送门: \(\text{CIRU - The area ...
- 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 ! ...
- SPOJ 8073 The area of the union of circles (圆并入门)
Sphere Online Judge (SPOJ) - Problem CIRU [求圆并的若干种算法,圆并扩展算法]_AekdyCoin的空间_百度空间 参考AekdyCoin的圆并算法解释,根据 ...
- [SPOJ-CIRU]The area of the union of circles/[BZOJ2178]圆的面积并
[SPOJ-CIRU]The area of the union of circles/[BZOJ2178]圆的面积并 题目大意: 求\(n(n\le1000)\)个圆的面积并. 思路: 对于一个\( ...
- SPOJ CIRU SPOJ VCIRCLE 圆的面积并问题
SPOJ VCIRCLE SPOJ CIRU 两道题都是给出若干圆 就面积并,数据规模和精度要求不同. 求圆面积并有两种常见的方法,一种是Simpson积分,另一种是几何法. 在这里给出几何方法. P ...
- SPOJ CIRU
SPOJ CIRU 题意 给出n个圆,求他们覆盖的面积. 解法 自适应Simpson,但需要将圆离散化一下,以保证我们查询的是一个连续的有圆的区间. 奇怪的是我没有离散化,样例都没有过,却把题给A了 ...
随机推荐
- 【题解】HAOI2011Problem b
第一次接触莫比乌斯反演,总之脑子都快要炸掉了……好难啊!本蒟蒻表示根本无法理解呜呜呜呜呜……不过在机房DL的帮助下总算是磕磕绊绊的A掉了这一题: 这道题目要我们的求的是:(1)ΣiΣj [gcd(i, ...
- 【NOIP模拟赛】Drink 二维链表+模拟
我觉得这道题的主旨应该是模拟,但是如果说他是二维链表的話也不為過.這道題的主體思路就是把原來旋轉點的O(n^2)變成了旋轉邊界的O(n).怎麼旋轉邊界呢,就好像是把原來的那些點都於上下左右四個點連線, ...
- echarts中图表过于靠左或靠右的情况解决办法。
经过好多次尝试,终于在http://blog.csdn.net/ainuser/article/details/76641963中得到解决. grid: { x: '30%', //相当于距离左边效果 ...
- eclipse关闭错误警告提示
- There is an overlap in the region chain
ERROR: (regions day_hotstatic,860010-2355010000_20140417_12_entry_00000000321,1398674475358.0dc20573 ...
- 清理/var/spool/clientmqueue目录释放大量空间
清理/var/spool/clientmqueue目录可以释放大量空间,具体命令是:ls | xargs rm -f 文件太大,rm -rf会由于参数太多而无法删除,所以需要用上面的命令. “Argu ...
- 计算1-1/x+1/x*x
// algo1-1.cpp 计算1-1/x+1/x*x. #include<stdio.h> #include<sys/timeb.h> void main() { time ...
- 前端跨域之jsonp跨域
jsonp跨域原理 原理:因为通过script标签引入的js是不受同源策略的限制的(比如baidu.com的页面加载了google.com的js).所以我们可以通过script标签引入一个js或者一个 ...
- 一个IT中专生在深圳的9年辛酸经历
一个IT中专生在深圳的9年辛酸经历 想一想来到深圳已经近10年了,感概万千呐!从一个身无分文的中专职校计算机毕业出来后,竟然大胆的南下(之前可是连我们那地区之外都没去过),现在有供完的房子,温柔的妻子 ...
- 【uva11468-Substring】AC自动机+dp
http://acm.hust.edu.cn/vjudge/problem/31655 题意:给定k个模板串,n个字符以及选择它的概率pro[i],要构造一个长度问L的字符串s,问s不包含任意一个模板 ...