dmkozyrev

232.cpp

Aug 25th, 2017
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.83 KB | None | 0 0
  1. #include <vector>
  2. #include <cmath>
  3. #include <cstdio>
  4. #include <algorithm>
  5.  
  6. const double EPS = 1e-15;
  7. const double PI = std::acos(-1.0);
  8.  
  9. struct Point {
  10.     double x, y;
  11.    
  12.     Point(double x = 0, double y = 0) : x(x), y(y) { }
  13.    
  14.     static Point read() {
  15.         double x, y;
  16.         scanf("%lf %lf", &x, &y);
  17.         return Point(x, y);
  18.     }
  19. };
  20.  
  21. struct Vector {
  22.     double x, y;
  23.    
  24.     operator Point() const {
  25.         return Point(x, y);
  26.     }
  27.    
  28.     Vector (double x, double y) : x(x), y(y) { }
  29.    
  30.     Vector(const Point & A = Point()) : x(A.x), y(A.y) { }
  31.    
  32.     Vector(const Point & A, const Point & B) : x(B.x-A.x), y(B.y - A.y) { }
  33. };
  34.  
  35. Vector operator * (double val, const Vector & A) {
  36.     return Vector(val * A.x, val * A.y);
  37. }
  38.  
  39. Vector operator + (const Vector & A, const Vector & B) {
  40.     return Vector(A.x + B.x, A.y + B.y);
  41. }
  42.  
  43. Vector operator - (const Vector & A, const Vector & B) {
  44.     return A + (-1.0) * B;
  45. }
  46.  
  47. double scal(const Vector & A, const Vector & B) {
  48.     return A.x * B.x + A.y * B.y;
  49. }
  50.  
  51. double norm2(const Vector & A) {
  52.     return scal(A, A);
  53. }
  54.  
  55. double norm(const Vector & A) {
  56.     return std::sqrt(norm2(A));
  57. }
  58.  
  59. double angle(const Vector & A, const Vector & B) {
  60.     return acos(scal(A, B) / norm(A) / norm(B));
  61. }
  62.  
  63. Vector rotate(const Vector & A, const double angle) {
  64.     double c = std::cos(angle), s = std::sin(angle);
  65.     return Vector(scal(A, Vector(c, -s)), scal(A, Vector(s, c)));
  66. }
  67.  
  68. struct Line {
  69.     Point A;
  70.    
  71.     Vector V;
  72.    
  73.     Line(const Point & A = Point(), const Vector & V = Vector()) : A(A), V(V) { }
  74.    
  75.     double val(const Point & C) const {
  76.         return scal(C-A, Vector(-V.y, V.x));
  77.     }
  78.    
  79.     int sign(const Point & C) const {
  80.         double v = val(C);
  81.         if (v > 0) {
  82.             return 1;
  83.         } else if (v < 0) {
  84.             return -1;
  85.         } else {
  86.             return 0;
  87.         }
  88.     }
  89. };
  90.  
  91. double dist(const Point & P, const Line & L) {
  92.     Vector V = P - L.A;
  93.     return norm(V) * std::sin(std::min(angle(V, -1.0 * L.V), angle(V, L.V))) + EPS;
  94. }
  95.  
  96. struct Circle {
  97.     Point C;
  98.    
  99.     double r;
  100.    
  101.     Circle(const Point & C = Point(), double r = 0) : C(C), r(r) { }
  102.    
  103.     static Circle read() {
  104.         Point C = Point::read();
  105.         double r;
  106.         scanf("%lf", &r);
  107.         return Circle(C, r);
  108.     }
  109. };
  110.  
  111. bool is_good(const Line & l, const std::vector<Circle> & circles, int ignored1, int ignored2) {
  112.     bool answer = true;
  113.     int sign1 = 0, sign2 = 0;
  114.     for (int i = 0; i < (int)circles.size(); ++i) {
  115.             if (i != ignored1 && i != ignored2 && dist(circles[i].C, l) < circles[i].r) {
  116.                 return false;
  117.             }
  118.            
  119.             if (l.sign(circles[i].C) > 0) {
  120.                 ++sign1;
  121.             } else if (l.sign(circles[i].C) < 0) {
  122.                 ++sign2;
  123.             } else {
  124.                 throw 1;
  125.             }
  126.        
  127.     }
  128.     return answer && sign1 > 0 && sign2 > 0;
  129. }
  130.  
  131. void check(bool q) {
  132.     if (!q) {
  133.         throw 1;
  134.     }
  135. }
  136.  
  137. int main() {
  138.     freopen("input.txt", "rt", stdin); 
  139. //  freopen("output.txt", "wt", stdout);   
  140.    
  141.     int n;
  142.     scanf("%d", &n);
  143.     if (n == 1) {
  144.         printf("YES");
  145.         return 0;
  146.     } else if (n == 2) {
  147.         printf("NO");
  148.         return 0;
  149.     }
  150.    
  151.     std::vector<Circle> circles;
  152.     circles.reserve(n);
  153.     for (int i = 0; i < n; ++i)
  154.         circles.push_back(Circle::read());
  155.    
  156.     for (int i = 0; i < n-1; ++i)
  157.         for (int j = i+1; j < n; ++j) {
  158.             auto c1 = circles[i], c2 = circles[j]; 
  159.            
  160.             if (c1.r > c2.r) {
  161.                 std::swap(c1, c2);
  162.             }
  163.            
  164.             Line l1, l2;
  165.             if (c1.r == c2.r) {
  166.                 auto v = c2.C-c1.C;
  167.                 v = rotate(v, PI / 2);
  168.                 v = c1.r / norm(v) * v;
  169.                 l1 = Line(c1.C+v, c2.C-c1.C);
  170.                 l2 = Line(c1.C-v, c2.C-c1.C);
  171.             } else {   
  172.                 double d = norm(c2.C-c1.C);
  173.                 double x = c1.r * d / (c2.r - c1.r);
  174.                 Vector v = 1.0 / norm(c1.C-c2.C) * (c1.C - c2.C);
  175.                 Point C = c1.C + x * v;
  176.                 v = -1.0 * v;
  177.                 double alpha = asin(c1.r / x);
  178.                 l1 = Line(C, rotate(v, alpha));
  179.                 l2 = Line(C, rotate(v, -alpha));
  180.             }
  181.            
  182.             if (is_good(l1, circles, i, j) || is_good(l2, circles, i, j)) {
  183.                 printf("NO");
  184.                 return 0;
  185.             }
  186.            
  187.         }
  188.        
  189.     printf("YES"); 
  190.     return 0;
  191. }
Advertisement
Add Comment
Please, Sign In to add comment