Codeforces Round #462 (Div. 2) E. A Colourful Prospect

E. A Colourful Prospect
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

Input

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

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

Output

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

Examples
input
Copy
3
0 0 1
2 0 1
4 0 1
output
4
input
Copy
3
0 0 2
3 0 2
6 0 2
output
6
input
Copy
3
0 0 2
2 0 2
1 1 2
output
8
Note

For the first example,

For the second example,

For the third example,

思路一:每次新添加一个圆时,求出与前面所有的圆产生的交点,有多少交点,就新增加多少区域。但有两种情况要特判,无交点时,区域数要加1;前两个圆相离或内含且第三个圆与前两个圆都有交点时,区域数要减1。

废话:你问我为什么区域数就是这个,我也是对数据画图得出的规律啊...之后学习了一下欧拉公式后:f = e - v + c + 1。f是区域数,c是连通块个数。其实这个规律就是欧拉公式啊...

另我是手推的圆交公式,该找一套板子了...

代码一(自己推交点的搓代码):

#include <iostream>
#include <fstream>
#include <sstream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <iomanip>
#include <cctype>
#include <cassert>
#include <bitset>
#include <ctime>

using namespace std;

#define pau system("pause")
#define ll long long
#define pii pair<int, int>
#define pb push_back
#define mp make_pair
#define clr(a, x) memset(a, x, sizeof(a))
#define pdd pair<double, double>

const double pi = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double EPS = 1e-9;

struct circle {
    ll x, y, r;
} c[3];
ll n;
vector<pdd> vec;
bool equ(pdd p1, pdd p2) {
    double x1 = p1.first, y1 = p1.second;
    double x2 = p2.first, y2 = p2.second;
    return fabs(x1 - x2) < EPS && fabs(y1 - y2) < EPS;
}
ll pow2(ll x) {return x * x;}
bool in(circle c1, circle c2) {
    int x1 = c1.x, y1 = c1.y, r1 = c1.r;
    int x2 = c2.x, y2 = c2.y, r2 = c2.r;
    int d1 = pow2(r1 - r2);
    int d2 = pow2(x1 - x2) + pow2(y1 - y2);
    return d1 > d2;
}
bool out(circle c1, circle c2) {
    int x1 = c1.x, y1 = c1.y, r1 = c1.r;
    int x2 = c2.x, y2 = c2.y, r2 = c2.r;
    int d1 = pow2(r1 + r2);
    int d2 = pow2(x1 - x2) + pow2(y1 - y2);
    return d1 < d2;
}
bool Insec(circle c1, circle c2) {
    ll x1 = c1.x, y1 = c1.y, r1 = c1.r;
    ll x2 = c2.x, y2 = c2.y, r2 = c2.r;
    if (x1 == x2 && y1 == y2) return false;
    const ll con = pow2(x2) + pow2(y2) + pow2(r1) - pow2(x1) - pow2(y1) - pow2(r2);
    if (x1 == x2) {
        ll a = 4 * (pow2(y2 - y1) + pow2(x2 - x1));
        ll b = 4 * (x1 - x2) * (con - 2 * (y2 - y1) * y1) - 8 * x1 * pow2(y2 - y1);
        ll c = 4 * pow2(y2 - y1) * pow2(x1) + pow2(con - 2 * (y2 - y1) * y1) - pow2(r1) * 4 * pow2(y2 - y1);
        ll det = b * b - 4 * a * c;
        //printf("%lld %lld %lld %lld
", con, a, b, c);
        if (det < 0) {
            return false;
        } else if (!det) {
            double _x1 = 1.0 * (-b) / (2 * a);
            double _y1 = (2 * (x1 - x2) * _x1 + con) / (2 * (y2 - y1));
            vec.pb(mp(_x1, _y1));
        } else {
            double sqr_det = sqrt(det);
            double _x1 = 1.0 * (-b + sqr_det) / (2 * a);
            double _x2 = 1.0 * (-b - sqr_det) / (2 * a);
            double _y1 = (2 * (x1 - x2) * _x1 + con) / (2 * (y2 - y1));
            double _y2 = (2 * (x1 - x2) * _x2 + con) / (2 * (y2 - y1));
            vec.pb(mp(_x1, _y1));
            vec.pb(mp(_x2, _y2));
        }
    } else {
        ll a = 4 * (pow2(x2 - x1) + pow2(y2 - y1));
        ll b = 4 * (y1 - y2) * (con - 2 * (x2 - x1) * x1) - 8 * y1 * pow2(x2 - x1);
        ll c = 4 * pow2(x2 - x1) * pow2(y1) + pow2(con - 2 * (x2 - x1) * x1) - pow2(r1) * 4 * pow2(x2 - x1);
        ll det = b * b - 4 * a * c;
        if (det < 0) {
            return false;
        } else if (!det) {
            double _y1 = 1.0 * (-b) / (2 * a);
            double _x1 = (2 * (y1 - y2) * _y1 + con) / (2 * (x2 - x1));
            vec.pb(mp(_x1, _y1));
        } else {
            double sqr_det = sqrt(det);
            double _y1 = 1.0 * (-b + sqr_det) / (2 * a);
            double _y2 = 1.0 * (-b - sqr_det) / (2 * a);
            double _x1 = (2 * (y1 - y2) * _y1 + con) / (2 * (x2 - x1));
            double _x2 = (2 * (y1 - y2) * _y2 + con) / (2 * (x2 - x1));
            vec.pb(mp(_x1, _y1));
            vec.pb(mp(_x2, _y2));
        }
    }
    return true;
}
int main() {
    scanf("%d", &n);
    for (ll i = 0; i < n; ++i) {
        scanf("%lld%lld%lld", &c[i].x, &c[i].y, &c[i].r);
    }
    ll ans = 2;
    for (ll i = 1; i < n; ++i) {
        vec.clear();
        int flag = 1;
        for (ll j = 0; j < i; ++j) {
            if (!Insec(c[i], c[j])) {
                flag = 0;
            }
        }
        sort(vec.begin(), vec.end());
        ll tt = vec.size();
        for (ll j = 0; j < (ll)vec.size() - 1; ++j) {
            if (equ(vec[j], vec[j + 1])) --tt;
        }
        if (i == 2 && (in(c[0], c[1]) || out(c[0], c[1])) && flag) --tt;
        ans += max(tt, 1ll);
        /*for (ll j = 0; j < vec.size(); ++j) {
            printf("%.3f %.3f
", vec[j].first, vec[j].second);
        }*/
    }
    printf("%d", ans);
    return 0;
}
原文地址:https://www.cnblogs.com/BIGTOM/p/8451530.html