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了 ...
随机推荐
- IIS注册asp.net4.0
1. 运行->cmd 2. cd C:\Windows\Microsoft.NET\Framework64\v4.0.30319 3. aspnet_regiis.exe -i
- 【CF edu 30 A. Chores】
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standa ...
- Codeforces Round #351 (VK Cup 2016 Round 3, Div. 2 Edition) A
A. Bear and Game time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...
- HDU 多校对抗赛 D Distinct Values
Distinct Values Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- sls语法:创建file,创建文件夹
http://blog.kukafei520.net/html/2014/942.html /tmp/aaa.txt: file.managed /tmp/salt_test: file.direct ...
- bzoj3790 manacher算法+贪心
紧跟jk大佬的步伐 这道题哇 因为机器一能生成回文串 所以我们只要用manacher跑一遍求出q[i]这样就把问题转化成了类似线段覆盖的题目 贪心就好了 至于,BIT优化dp我不会所以直接贪心了 注意 ...
- 【BZOJ】1708: [Usaco2007 Oct]Money奶牛的硬币
[算法]DP [题解] 如果每个排列算一种,则令f[i]表示凑成面值为i的方案数,容易推出f[i]+=f[i-a[j]]. 现在是每个组合才算一种,令f[i][j]第二维表示只使用前j种面值,f[i] ...
- php session 阻塞 过期不自动清除session文件
php默认session session_start后,php就会打开session文件,然后同一时间用户再用那个session_id访问,就会被前面那个请求阻塞直到前面一个访问结束才会释放文件在使 ...
- #error#storyboard#xib#解决方案
https://www.evernote.com/shard/s227/sh/cad7d5f5-8e81-4b3b-908f-5d8eee7d11e2/928786149cf9a103a74626 ...
- 以root启动pycharm
在使用scapy模块的时候提示permitted就猜想可能是权限问题.然后换成root启动啥事情都没了. 由于本机是deepin先找到pycharm.sh脚本 然后再执行sudo ./pycharm. ...