Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <vector>
- #include <cmath>
- #include <cstdio>
- #include <algorithm>
- const double EPS = 1e-15;
- const double PI = std::acos(-1.0);
- struct Point {
- double x, y;
- Point(double x = 0, double y = 0) : x(x), y(y) { }
- static Point read() {
- double x, y;
- scanf("%lf %lf", &x, &y);
- return Point(x, y);
- }
- };
- struct Vector {
- double x, y;
- operator Point() const {
- return Point(x, y);
- }
- Vector (double x, double y) : x(x), y(y) { }
- Vector(const Point & A = Point()) : x(A.x), y(A.y) { }
- Vector(const Point & A, const Point & B) : x(B.x-A.x), y(B.y - A.y) { }
- };
- Vector operator * (double val, const Vector & A) {
- return Vector(val * A.x, val * A.y);
- }
- Vector operator + (const Vector & A, const Vector & B) {
- return Vector(A.x + B.x, A.y + B.y);
- }
- Vector operator - (const Vector & A, const Vector & B) {
- return A + (-1.0) * B;
- }
- double scal(const Vector & A, const Vector & B) {
- return A.x * B.x + A.y * B.y;
- }
- double norm2(const Vector & A) {
- return scal(A, A);
- }
- double norm(const Vector & A) {
- return std::sqrt(norm2(A));
- }
- double angle(const Vector & A, const Vector & B) {
- return acos(scal(A, B) / norm(A) / norm(B));
- }
- Vector rotate(const Vector & A, const double angle) {
- double c = std::cos(angle), s = std::sin(angle);
- return Vector(scal(A, Vector(c, -s)), scal(A, Vector(s, c)));
- }
- struct Line {
- Point A;
- Vector V;
- Line(const Point & A = Point(), const Vector & V = Vector()) : A(A), V(V) { }
- double val(const Point & C) const {
- return scal(C-A, Vector(-V.y, V.x));
- }
- int sign(const Point & C) const {
- double v = val(C);
- if (v > 0) {
- return 1;
- } else if (v < 0) {
- return -1;
- } else {
- return 0;
- }
- }
- };
- double dist(const Point & P, const Line & L) {
- Vector V = P - L.A;
- return norm(V) * std::sin(std::min(angle(V, -1.0 * L.V), angle(V, L.V))) + EPS;
- }
- struct Circle {
- Point C;
- double r;
- Circle(const Point & C = Point(), double r = 0) : C(C), r(r) { }
- static Circle read() {
- Point C = Point::read();
- double r;
- scanf("%lf", &r);
- return Circle(C, r);
- }
- };
- bool is_good(const Line & l, const std::vector<Circle> & circles, int ignored1, int ignored2) {
- bool answer = true;
- int sign1 = 0, sign2 = 0;
- for (int i = 0; i < (int)circles.size(); ++i) {
- if (i != ignored1 && i != ignored2 && dist(circles[i].C, l) < circles[i].r) {
- return false;
- }
- if (l.sign(circles[i].C) > 0) {
- ++sign1;
- } else if (l.sign(circles[i].C) < 0) {
- ++sign2;
- } else {
- throw 1;
- }
- }
- return answer && sign1 > 0 && sign2 > 0;
- }
- void check(bool q) {
- if (!q) {
- throw 1;
- }
- }
- int main() {
- freopen("input.txt", "rt", stdin);
- // freopen("output.txt", "wt", stdout);
- int n;
- scanf("%d", &n);
- if (n == 1) {
- printf("YES");
- return 0;
- } else if (n == 2) {
- printf("NO");
- return 0;
- }
- std::vector<Circle> circles;
- circles.reserve(n);
- for (int i = 0; i < n; ++i)
- circles.push_back(Circle::read());
- for (int i = 0; i < n-1; ++i)
- for (int j = i+1; j < n; ++j) {
- auto c1 = circles[i], c2 = circles[j];
- if (c1.r > c2.r) {
- std::swap(c1, c2);
- }
- Line l1, l2;
- if (c1.r == c2.r) {
- auto v = c2.C-c1.C;
- v = rotate(v, PI / 2);
- v = c1.r / norm(v) * v;
- l1 = Line(c1.C+v, c2.C-c1.C);
- l2 = Line(c1.C-v, c2.C-c1.C);
- } else {
- double d = norm(c2.C-c1.C);
- double x = c1.r * d / (c2.r - c1.r);
- Vector v = 1.0 / norm(c1.C-c2.C) * (c1.C - c2.C);
- Point C = c1.C + x * v;
- v = -1.0 * v;
- double alpha = asin(c1.r / x);
- l1 = Line(C, rotate(v, alpha));
- l2 = Line(C, rotate(v, -alpha));
- }
- if (is_good(l1, circles, i, j) || is_good(l2, circles, i, j)) {
- printf("NO");
- return 0;
- }
- }
- printf("YES");
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment