[codeforces934E]A Colourful Prospect

试题描述

Firecrackers scare Nian the monster, but they're wayyyyy too noisy! Maybe fireworks make a nice complement.

Little Tommy is watching a firework show. As circular shapes spread across the sky, a splendid view unfolds on the night of Lunar New Year's eve.

A wonder strikes Tommy. How many regions are formed by the circles on the sky? We consider the sky as a flat plane. A region is a connected part of the plane with positive area, whose bound consists of parts of bounds of the circles and is a curve or several curves without self-intersections, and that does not contain any curve other than its boundaries. Note that exactly one of the regions extends infinitely.

求 \(n\) 个圆将平面划分成的区域个数。

输入

The first line of input contains one integer \(n\) \((1 \le n \le 3)\), denoting the number of circles.

The following \(n\) lines each contains three space-separated integers \(x\), \(y\) and \(r\) \(( - 10 \le x, y \le 10, 1 \le r \le 10)\), describing a circle whose center is \((x, y)\) and the radius is \(r\). No two circles have the same \(x\), \(y\) and \(r\) at the same time.

输出

Print a single integer — the number of regions on the plane.

输入示例1

3
0 0 1
2 0 1
4 0 1

输出示例1

4

输入示例2

3
0 0 2
3 0 2
6 0 2

输出示例2

6

输入示例3

3
0 0 2
2 0 2
1 1 2

输出示例3

8

数据规模及约定

见“输入

题解

这题要用到平面上的欧拉公式:\(V - E + R = C + 1\),其中 \(V\)(vertex) 表示交点数目,\(E\)(edge) 表示边数,\(R\)(region) 表示区域数,\(C\)(connection) 用来分割的线所构成的连通块个数。(英文是我自己 YY 的)

然后这题就好做了,\(V\) 非常好求,两两圆求一下交点去重即可;\(E\) 就是每个圆上的交点个数之和(注意如果一个圆不与任何圆相交,那么它不能算作一条边);\(C\) 也可以用并查集啥的统计一下;于是我们就算出 \(R\) 了。

分类讨论的话可能这辈子做不完这道题了。而且 \(n\) 可以出到 \(1000\) 级别

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
#define rep(i, s, t) for(int i = (s), mi = (t); i <= mi; i++)
#define dwn(i, s, t) for(int i = (s), mi = (t); i >= mi; i--) int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} const double eps = 1e-9; struct Vector {
double x, y;
Vector() {}
Vector(double _, double __): x(_), y(__) {}
Vector operator - (const Vector& t) const { return Vector(x - t.x, y - t.y); }
double len() { return sqrt(x * x + y * y); }
bool operator < (const Vector& t) const { return abs(x - t.x) > eps ? x < t.x : y < t.y; }
bool operator == (const Vector& t) const { return abs(x - t.x) <= eps && abs(y - t.y) <= eps; }
} ps[100], crs[5][100];
int cp, cc[5];
struct Circle {
Vector p; double r;
Circle() {}
Circle(Vector _, double __): p(_), r(__) {}
Vector point(double a) { return Vector(cos(a) * r + p.x, sin(a) * r + p.y); }
} cs[5]; double angle(Vector x) { return atan2(x.y, x.x); }
vector <Vector> getcross(Circle c1, Circle c2) {
vector <Vector> p; p.resize(0);
Vector t = c2.p - c1.p;
double d = t.len(), a = angle(t);
if(abs(d) <= eps) return p;
if(d < abs(c2.r - c1.r) || d > c2.r + c1.r) return p;
double da = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
Vector p1 = c1.point(a + da), p2 = c1.point(a - da);
p.push_back(p1);
if(p1 == p2) return p;
p.push_back(p2);
return p;
} int fa[5];
int findset(int x) { return x == fa[x] ? x : fa[x] = findset(fa[x]); } int main() {
int n = read();
rep(i, 1, n) {
int x = read(), y = read(), r = read();
cs[i] = Circle(Vector(x, y), r);
fa[i] = i;
} int V, E = 0, C = n;
rep(i, 1, n) {
rep(j, 1, n) if(i != j) {
vector <Vector> tmp = getcross(cs[i], cs[j]);
for(auto k : tmp) crs[i][++cc[i]] = k;
if(tmp.size() > 0) {
int u = findset(i), v = findset(j);
if(u != v) fa[v] = u, C--;
}
}
sort(crs[i] + 1, crs[i] + cc[i] + 1);
cc[i] = unique(crs[i] + 1, crs[i] + cc[i] + 1) - crs[i] - 1;
E += cc[i];
/*printf("cs[%d]:\n", i);
rep(j, 1, cc[i]) printf("(%.5lf, %.5lf)\n", crs[i][j].x, crs[i][j].y); // */
rep(j, 1, cc[i]) ps[++cp] = crs[i][j];
}
sort(ps + 1, ps + cp + 1);
cp = unique(ps + 1, ps + cp + 1) - ps - 1;
V = cp; // printf("E: %d, V: %d, C: %d\n", E, V, C);
printf("%d\n", E - V + C + 1); // */ return 0;
}

[codeforces934E]A Colourful Prospect的更多相关文章

  1. codeforces 462div.2

    A A Compatible Pair standard input/output 1 s, 256 MB    x1916 B A Prosperous Lot standard input/out ...

  2. 【HDU4419 Colourful Rectangle】 线段树面积并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:给你n个矩形,每个矩形都有一种颜色,矩形覆盖会出现另外一种颜色,问你所有矩形中不同的颜 ...

  3. HDU 4419 Colourful Rectangle --离散化+线段树扫描线

    题意: 有三种颜色的矩形n个,不同颜色的矩形重叠会生成不同的颜色,总共有R,G,B,RG,RB,GB,RGB 7种颜色,问7种颜色每种颜色的面积. 解法: 很容易想到线段树扫描线求矩形面积并,但是如何 ...

  4. HDU 4419 Colourful Rectangle(线段树+扫描线)

    题目链接 主要是pushup的代码,其他和区间更新+扫描线差不多. 那个区间如果要再刷一层x,那么sum[x][rt] = que[r+1] - que[l];但是如果原本有颜色为i,颜色将会变成i| ...

  5. [HDU 4419] Colourful Rectangle (扫描线 矩形面积并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 题目大意:比矩形面积并多了颜色,问染成的每种颜色的面积. 矩形面积并的扫描线维护的是长度,这道题 ...

  6. HDU-4419 Colourful Rectangle 矩形多面积并

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4419 利用二进制,R为1.G为2.B为4,然后通过异或运算可以得到其它组合颜色.建立7颗线段树,每颗线 ...

  7. hdu 4419 Colourful Rectangle

    http://acm.hdu.edu.cn/showproblem.php?pid=4419 题意:给出3种颜色,重叠会生成新的颜色,然后有一些矩形,求出每种颜色的面积. 转化为二进制表示颜色:001 ...

  8. hdu4419 Colourful Rectangle 12年杭州网络赛 扫描线+线段树

    题意:给定n个矩形,每个矩形有一种颜色,RGB中的一种.相交的部分可能为RG,RB,GB,RGB,问这n个矩形覆盖的面积中,7种颜色的面积分别为多少 思路:把x轴离散化做扫描线,线段树维护一个扫描区间 ...

  9. Colourful Rectangle【扫描线】

    题目链接 很明显的可以发现是一个扫描线的问题,但是怎么处理区域呢,发现只有三种颜色,也就是最多也就是7种状态,那么我们可以进行一个状态压缩即可. 但是,在向上pushup的时候,存在我们要以子树的状态 ...

随机推荐

  1. lnmp安装后,phpmyadmin空白

    使用lnmp 一键安装后,运行phpinfo是没有问题的,说明php没有问题,但是运行phpmyadmin确实一片空白,网上说的解决方案有几种: 1.config.inc.php增加一个配置$cfg[ ...

  2. glibc2.12升级至2.15

    1.操作系统版本 [root@localhost ~]# cat /etc/redhat-release #CentOS release 6.9 (Final) 2.当前glibc版本 [root@l ...

  3. Struts2之基于配置的字段校验

    上一篇struts2之输入校验介绍了手动完成输入校验,也即依靠重写validate方法和validateXxx方法,指定请求某个方法时对传入的参数进行校验. 本篇介绍基于配置的字段校验.下面是登录的常 ...

  4. python__高级 : @修饰器(装饰器)的理解

    以下是第一次了解的时候写的东西,有的地方理解不正确,虽已改正但是太片面,请直接看下面第二次修改加上的内容. ---------------------------------------------- ...

  5. Allowed memory size of 134217728 bytes exhausted (tried to allocate 2 bytes)

    出现  Allowed memory size of 134217728 bytes exhausted (tried to allocate 2 bytes)时在php.ini文件中配置 memor ...

  6. 解决win10子系统Ubuntu新装的mysql 不能root登陆方法

    步骤一:打开终端 $sudo /etc/init.d/mysql stop $sudo mkdir -p /var/run/mysqld $sudo chown mysql:mysql /var/ru ...

  7. 使用windows live writer写cnblog-1 安装wlr

    Writer:在本地编辑有声在色的博客内容,发布到你的网络博客!   离线安装文件下载地址:http://dx1.itopdog.cn/soft/wlsetup-all.rar 下了好几个离线版本的, ...

  8. Oozie 安装及 examples app 的使用

    参考文档 一.Building OOzie 特别注意的是修改Pom.xml文件中的版本与本机中安装的版本相同 二. install Oozie 1.为 hadoop 添加 Oozie 的代理用户,添加 ...

  9. Oozie 实战之 shell

    说明:使用 shell action 执行 shell 脚本 hive-select-test.sh 来通过已经配置好的 Hive -f 来执行 HQL 查询脚本文件 select.sql 1.创建脚 ...

  10. SSM框架的简单搭建

    转:https://blog.csdn.net/zhshulin/article/details/37956105 Spring+SpringMVC+MyBatis spring       : 4. ...