• [codeforces934E]A Colourful Prospect


    [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]:
    ", i);
    		rep(j, 1, cc[i]) printf("(%.5lf, %.5lf)
    ", 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
    ", E, V, C);
    	printf("%d
    ", E - V + C + 1); // */
    	
    	return 0;
    }
    
  • 相关阅读:
    express和koa,node.js的框架的区别——英文版
    深入javascript系列
    命名函数表达式相关
    闭包与作用域链,思考题目
    iOS开发之身份证号码校验
    iOS8中使用CoreLocation定位[转]
    iOS开发之应用内检测手机锁屏,解锁状态
    iOS8设置应用图标红点的权限问题
    删除已经配置的类库和移除CocoaPods[转]
    如何在Xcode6中添加空模板
  • 原文地址:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/8453565.html
Copyright © 2020-2023  润新知