Advertisement
IlidanBabyRage

ecircle.cpp

Jun 9th, 2015
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.55 KB | None | 0 0
  1. #include <iostream>
  2. #include <utility>
  3.  
  4. #define X first
  5. #define Y second
  6.  
  7. using namespace std;
  8.  
  9. typedef pair<double, double> pdd;
  10. typedef pair<pdd, double> pcr;
  11.  
  12. //returns pair of center coords and radius^2
  13. pcr makeCircle(double *nx, double *ny, int n);
  14.  
  15. int main(){
  16.    
  17.     int n, m;
  18.  
  19.     cin >> n >> m;
  20.  
  21.     double *nx = new double[n];
  22.     double *ny = new double[n];
  23.     double *mx = new double[m];
  24.     double *my = new double[m];
  25.     for (int i = 0; i < n; i++){
  26.         cin >> nx[i] >> ny[i];
  27.     }
  28.     for (int i = 0; i < m; i++){
  29.         cin >> mx[i] >> my[i];
  30.     }
  31.  
  32.     if (n < 2 || m < 2){
  33.         cout << "YES" << endl;
  34.         return 0;
  35.     }
  36.    
  37.     //get the first circle
  38.     pcr ncir = makeCircle(nx, ny, n);
  39.     double cx, cy, rsqr, tmpr;
  40.     //remains true if all of "m" coords are outside of the circle
  41.     bool success = true;
  42.     //just renaming for convenience
  43.     cx = ncir.first.X;
  44.     cy = ncir.first.Y;
  45.     rsqr = ncir.second;
  46.     for (int i = 0; i < m; i++){
  47.         //calculating distance^2 between m[i] and center of n_circle
  48.         tmpr = (mx[i] - cx) * (mx[i] - cx) + (my[i] - cy) * (my[i] - cy);
  49.         //if that distance is lesser than the radius of the n_circle, try with another circle
  50.         if (tmpr <= rsqr){
  51.             success = false;
  52.             break;
  53.         }
  54.     }
  55.     //if success == true then all of the "m" dots are outside of the n_circle
  56.     if (success)
  57.         cout << "YES" << endl;
  58.     else{
  59.         //get the second circle
  60.         pcr mcir = makeCircle(mx, my, m);
  61.         //renaming again
  62.         cx = mcir.first.X;
  63.         cy = mcir.first.Y;
  64.         rsqr = mcir.second;
  65.         //set success to true just like in previous case
  66.         success = true;
  67.         for (int i = 0; i < n; i++){
  68.             tmpr = (nx[i] - cx) * (nx[i] - cx) + (ny[i] - cy) * (ny[i] - cy);
  69.             if (tmpr <= rsqr){
  70.                 cout << "NO" << endl;
  71.                 success = false;
  72.                 break;
  73.             }
  74.         }
  75.         if (success)
  76.             cout << "YES" << endl;
  77.     }
  78.  
  79.     delete [] nx;
  80.     delete [] ny;
  81.     delete [] mx;
  82.     delete [] my;
  83.  
  84.     return 0;
  85. }
  86.  
  87. pcr makeCircle(double *nx, double *ny, int n){
  88.     if (n < 2){
  89.         return pcr(pdd(nx[0], ny[0]), 0);
  90.     }
  91.     double max;
  92.     int maxa, maxb;
  93.     //find two points a, b : distance(a,b) is maximal
  94.     for (int i = 0; i < n - 1; i++){
  95.         double tmp;
  96.         for (int j = i + 1; j < n; j++){
  97.             tmp = (nx[i] - nx[j]) * (nx[i] - nx[j]) + (ny[i] - ny[j]) * (ny[i] - ny[j]);
  98.             if (tmp > max){
  99.                 max = tmp;
  100.                 maxa = i;
  101.                 maxb = j;
  102.             }
  103.         }
  104.     }
  105.  
  106.     double cx, cy, ax, ay, bx, by;
  107.     //renaming for convenience
  108.     ax = nx[maxa];
  109.     ay = ny[maxa];
  110.     bx = nx[maxb];
  111.     by = ny[maxb];
  112.     //center of the circle
  113.     cx = (ax + bx) / 2.;
  114.     cy = (ay + by) / 2.;
  115.     //radius^2
  116.     double rsqr = (ax - cx) * (ax - cx) + (ay - cy) * (ay - cy);
  117.     max = 0;
  118.     int max2;
  119.     //find dot N : distance((cx, cy), N) is maximal
  120.     for (int i = 0; i < n; i++){
  121.         double tmpr;
  122.         tmpr = (nx[i] - cx) * (nx[i] - cx) + (ny[i] - cy) * (ny[i] - cy);
  123.         if (tmpr > max){
  124.             max = tmpr;
  125.             max2 = i;
  126.         }
  127.     }
  128.     //renaming
  129.     double x, y;
  130.     x = nx[max2];
  131.     y = ny[max2];
  132.     //if new dot lies outside of the radius, remake the circle
  133.     if (max > rsqr){
  134.         if (ax == bx){
  135.             //vertical
  136.             cx = (ax * ax + ay * ay - y * y - x * x + 2 * cy * (y - ay)) / (2. * (ax - x));
  137.         }else if(ay == by){
  138.             //horizontal
  139.             cy = (-ax * ax - ay * ay + y * y + x * x + 2 * cx * (x - ax)) / (2. * (y - ay));
  140.         }else{
  141.             double k, b;
  142.             k = -1 / ((ay - by) / (ax - bx));
  143.             b = cy - cx * k;
  144.             // (x - cx)^2 + (y - cy)^2 == (ax - cx)^2 + (ay - cy) ^ 2
  145.             // cy == k * сx + b
  146.             cx = (ax * ax + ay * ay - y * y - x * x - 2 * (ay - y) * b) / (2. * (ax - x + k * (ay - y)));
  147.             cy = cx * k + b;
  148.             rsqr = (ax - cx) * (ax - cx) + (ay - cy) * (ay - cy);
  149.         }
  150.     }
  151.  
  152.     return pcr(pdd(cx, cy), rsqr);
  153. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement