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

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

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<double, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 0x3f3f3f3f3f3f;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e4 + 10;
const int mod = 1e6;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c){
return r >= 0 && r < n && c >= 0 && c < m;
} int dcmp(double x){
if(fabs(x) < eps) return 0;
if(x > 0) return 1;
return -1;
}
double sqr(double x){ return x * x; } struct Point{
double x, y;
Point(){ }
Point(double a, double b) : x(a), y(b) { }
void input(){
scanf("%lf %lf", &x, &y);
}
friend Point operator + (const Point &a, const Point &b){
return Point(a.x + b.x, a.y + b.y);
}
friend Point operator - (const Point &a, const Point &b){
return Point(a.x - b.x, a.y - b.y);
}
friend bool operator == (const Point &a, const Point &b){
return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}
friend Point operator * (const Point &a, const double &b){
return Point(a.x * b, a.y * b);
}
friend Point operator * (const double &b, const Point &a){
return Point(a.x * b, a.y * b);
}
friend Point operator / (const Point &a, const double &b){
return Point(a.x / b, a.y / b);
}
double norm(){
return sqrt(sqr(x) + sqr(y));
}
};
double cross(const Point &a, const Point &b){
return a.x * b.y - a.y * b.x;
}
struct Circle{
Point p;
double r;
bool operator < (const Circle &o) const{
if(dcmp(r-o.r) != 0) return dcmp(r-o.r) == -1;
if(dcmp(p.x-o.p.x) != 0) return dcmp(p.x - o.p.x) == -1;
return dcmp(p.y - o.p.y) == -1;
}
bool operator == (const Circle &o) const{
return dcmp(r - o.r) == 0 && dcmp(p.x - o.p.x) == 0 && dcmp(p.y - o.p.y) == 0;
}
};
Point rotate(const Point &p, double cost, double sint){
double x = p.x, y = p.y;
return Point(x*cost - y*sint, x*sint + y*cost);
} pair<Point, Point> crossPoint(Point ap, double ar, Point bp, double br){
double d = (ap - bp).norm();
double cost = (ar*ar + d*d - br*br) / (2.0*ar*d);
double sint = sqrt(1.0 - cost*cost);
Point v = (bp - ap) / (bp - ap).norm() * ar;
return make_pair(ap+rotate(v, cost, -sint), ap+rotate(v, cost, sint));
} pair<Point, Point> crossPoint(const Circle &a, const Circle &b){
return crossPoint(a.p, a.r, b.p, b.r);
}
Circle c[maxn], tc[maxn];
#include<complex>
struct Node{
Point p;
double a;
int d;
Node(const Point &pp, double aa, int dd) : p(pp), a(aa), d(dd) { }
bool operator < (const Node &o) const{
return a < o.a;
}
};
double arg(Point p){
return arg(complex<double> (p.x, p.y));
} double solve(){
sort(tc, tc + m);
m = unique(tc, tc + m) - tc;
n = 0;
for(int i = m-1; i >= 0; --i){
bool ok = true;
for(int j = i+1; j < m; ++j){
double d = (tc[i].p - tc[j].p).norm();
if(dcmp(d - abs(tc[i].r - tc[j].r)) <= 0){
ok = false; break;
}
}
if(ok) c[n++] = tc[i];
}
double ans = 0.0;
for(int i = 0; i < n; ++i){
vector<Node> event;
Point boundary = c[i].p + Point(-c[i].r, 0);
event.push_back(Node(boundary, -PI, 0));
event.push_back(Node(boundary, PI, 0));
for(int j = 0; j < n; ++j){
if(i == j) continue;
double d = (c[i].p - c[j].p).norm();
if(dcmp(d - (c[i].r + c[j].r)) < 0){
pair<Point, Point> ret = crossPoint(c[i], c[j]);
double x = arg(ret.first - c[i].p);
double y = arg(ret.second - c[i].p);
if(dcmp(x - y) > 0){
event.push_back(Node(ret.first, x, 1));
event.push_back(Node(boundary, PI, -1));
event.push_back(Node(boundary, -PI, 1));
event.push_back(Node(ret.second, y, -1));
}
else{
event.push_back(Node(ret.first, x, 1));
event.push_back(Node(ret.second, y, -1));
}
}
}
sort(event.begin(), event.end());
int sum = event[0].d;
for(int j = 1; j < event.size(); ++j){
if(sum == 0){
ans += cross(event[j-1].p, event[j].p) / 2.0;
double x = event[j-1].a;
double y = event[j].a;
double area = c[i].r * c[i].r * (y-x) / 2.0;
Point v1 = event[j-1].p - c[i].p;
Point v2 = event[j].p - c[i].p;
area -= cross(v1, v2) / 2.0;
ans += area;
}
sum += event[j].d;
}
}
return ans;
} int main(){
while(scanf("%d", &n) == 1){
m = 0;
for(int i = 0; i < n; ++i){
tc[m].p.input();
scanf("%lf", &tc[m].r);
if(dcmp(tc[m].r) <= 0) continue;
++m;
}
printf("%.3f\n", solve());
}
return 0;
}

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. API网关如何实现对服务下线实时感知

    上篇文章<Eureka 缓存机制>介绍了Eureka的缓存机制,相信大家对Eureka 有了进一步的了解,本文将详细介绍API网关如何实现服务下线的实时感知. 一.前言 在基于云的微服务应 ...

  2. 如何将mysql的路径加入环境变量

    1.打开终端,输入: cd ~ 会进入~文件夹 2.然后输入:touch .bash_profile 回车执行后, 2.再输入:open -e .bash_profile 会在TextEdit中打开这 ...

  3. mysql导入数据库_仅仅用frm向mysql导入表结构

    网上一个连接mysql的jsp代码段,给了数据库的备份文件.可是仅仅有frm, mysql的每张表有三个文件.各自是,*.frm是描写叙述了表的结构.*.MYD保存了表的数据记录.*.MYI则是表的索 ...

  4. Spring AOP(转载)

    此前对于AOP的使用仅限于声明式事务,除此之外在实际开发中也没有遇到过与之相关的问题.最近项目中遇到了以下几点需求,仔细思考之后,觉得采用AOP 来解决.一方面是为了以更加灵活的方式来解决问题,另一方 ...

  5. 在zend framework框架中try{}catch(Exception e){}的跳转问题

    请勿盗版,转载请加上出处http://blog.csdn.net/yanlintao1 首先我先说明我遇到的问题 try{ //导入学生信息 $ModelStudent->insert($dat ...

  6. Sum It Up POJ 1564 HDU 杭电1258【DFS】

    Problem Description Given a specified total t and a list of n integers, find all distinct sums using ...

  7. EasyHLS实现将IPCamera摄像机的RTSP流转成HLS(ts+m3u8)直播输出

    本文转自:http://www.cnblogs.com/babosa/p/6033039.html EasyHLS EasyHLS是EasyDarwin开源流媒体团队开发的一款HLS打包库,接口非常简 ...

  8. c# vs2010 连接access数据库

    第一次在博客园写博文,由于文采不怎么好,即使是自己很熟悉的东西,写起来也会感觉到不知从何讲起,我想写的多了就好了. 这篇文章主要是介绍怎么用c# 语言 vs2010连接access数据库的,连接字符串 ...

  9. Java类加载器( 死磕7)

    [正文]Java类加载器(  CLassLoader )死磕7:  基于加密的自定义网络加载器 本小节目录 7.1. 加密传输Server端的源码 7.2. 加密传输Client端的源码 7.3. 使 ...

  10. Geoffrey E. Hinton

    https://www.cs.toronto.edu/~hinton/ Geoffrey E. Hinton I am an Engineering Fellow at Google where I ...