Advertisement
Guest User

Untitled

a guest
Dec 17th, 2017
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.59 KB | None | 0 0
  1. #include <algorithm>
  2. #include <cassert>
  3. #include <cilk/cilk.h>
  4. #include <cstdio>
  5. #include <iostream>
  6. #include <vector>
  7. using namespace std;
  8.  
  9. const int N = 1123456;
  10.  
  11. struct Point {
  12.     int x, y;
  13.     Point() {}
  14.     Point(int x, int y): x(x), y(y) {}
  15.     Point operator+(const Point& o) const { return Point(x+o.x, y+o.y); }
  16.     Point operator-(const Point& o) const { return Point(x-o.x, y-o.y); }
  17.     int operator%(const Point& o) const {
  18.         return x*o.y - y*o.x;
  19.     }
  20.     bool operator<(const Point& o) const {
  21.         return x != o.x ? x < o.x : y < o.y;
  22.     }
  23. };
  24.  
  25. typedef Point Vector;
  26. typedef vector<Point> Polygon;
  27.  
  28. int n;
  29. Polygon point;
  30.  
  31. inline int ccw(const Point& p, const Point& q, const Point& r) {
  32.     return (q - p) % (r - p);
  33. }
  34.  
  35. Polygon convex_hull_sequential() {
  36.     Polygon hull(n);
  37.     int k = 0;
  38.     hull[k++] = point[0];
  39.     for (int i = 1; i < n; i++) {
  40.         while (k > 1 && ccw(hull[k-2], hull[k-1], point[i]) >= 0) k--;
  41.         hull[k++] = point[i];
  42.     }
  43.     // for (int i = n-2, lim = k; i >= 0; i--) {
  44.     //     while (k > lim && ccw(hull[k-2], hull[k-1], point[i]) >= 0) k--;
  45.     //     hull[k++] = point[i];
  46.     // }
  47.     // k--;
  48.     hull.resize(k);
  49.  
  50.     return hull;
  51. }
  52.  
  53. Polygon convex_hull_parallel(int l, int r) {
  54.     // if size is <= 4, bruteforce solution
  55.     if (r-l < 6) {
  56.         assert(l < r);
  57.         Polygon UH(r-l+1);
  58.         int k = 0;
  59.         UH[k++] = point[l];
  60.         // if (l == 4 and r == 7) printf(":: %d %d\n", point[l].x, point[l].y);
  61.         for (int i = l+1; i <= r; i++) {
  62.             while (k > 1 && ccw(UH[k-2], UH[k-1], point[i]) >= 0) k--;
  63.             UH[k++] = point[i];
  64.             // if (l == 4 and r == 7) printf("%d %d\n", point[i].x, point[i].y);
  65.         }
  66.         // if (l == 4 and r == 7) puts("");
  67.         UH.resize(k);
  68.         return UH;
  69.     }
  70.    
  71.     // divide  
  72.     int m = (l+r)/2;
  73.     Polygon UH1 = convex_hull_parallel(l, m);
  74.     Polygon UH2 = convex_hull_parallel(m+1, r);
  75.  
  76.     printf("UH1: %d %d\n", l, m);
  77.     for (const Point& p: UH1) printf("%d %d\n", p.x, p.y);
  78.  
  79.     printf("UH2: %d %d\n", m+1, r);
  80.     for (const Point& p: UH2) printf("%d %d\n", p.x, p.y);
  81.  
  82.     // conquer
  83.     // TODO: don't create new vector to return
  84.     int s = UH1.size(), t = UH2.size();
  85.  
  86.     // double binary search to find upper commom tangent
  87.     int l1 = 0, r1 = s-1, l2, r2;
  88.     while (l1 < r1) {
  89.         int m1 = (l1+r1)/2;
  90.         l2 = 0, r2 = t-1;
  91.         while (l2 < r2) {
  92.             int m2 = (l2+r2)/2;
  93.             int abovePred = ccw(UH1[m1], UH2[(m2+t-1)%t], UH2[m2]) >= 0;
  94.             int aboveSucc = ccw(UH1[m1], UH2[(m2+1)%t], UH2[m2]) >= 0;
  95.             if (abovePred and aboveSucc) {
  96.                 l2 = r2 = m2;
  97.             } else if (abovePred) {
  98.                 l2 = m2+1;
  99.             } else {
  100.                 r2 = m2-1;
  101.             }
  102.         }
  103.         int abovePred = ccw(UH2[l2], UH1[m1], UH1[(m1+s-1)%s]) >= 0;
  104.         int aboveSucc = ccw(UH2[l2], UH1[m1], UH1[(m1+1)%s]) >= 0;
  105.         if (abovePred and aboveSucc) {
  106.             l1 = r1 = m1;
  107.         } else if (abovePred) {
  108.             l1 = m1+1;
  109.         } else {
  110.             r1 = m1-1;
  111.         }
  112.     }
  113.  
  114.     printf("UH1[l1]: %d %d\n", UH1[l1].x, UH1[l1].y);
  115.     printf("UH2[l2]: %d %d\n\n", UH2[l2].x, UH2[l2].y);
  116.  
  117.     Polygon UH(l1+1+t-l2);
  118.     for (int i = 0; i < l1+1; ++i)
  119.         UH[i] = UH1[i];
  120.     for (int i = 0; i < t-l2; ++i)
  121.         UH[l1+1+i] = UH2[l2+i];
  122.  
  123.     return UH;
  124. }
  125.  
  126. int main() {
  127.  
  128.     srand(time(NULL));
  129.  
  130.     // get input data
  131.     scanf("%d", &n);
  132.     // n = 256;
  133.     point.resize(n);
  134.     // printf("%d\n", n);
  135.     for (int i = 0; i < n; ++i) {
  136.         scanf("%d %d", &point[i].x, &point[i].y);
  137.         // point[i] = Point(rand()%2048, rand()%2048);
  138.         // printf("%d %d\n", point[i].x, point[i].y);
  139.     }
  140.  
  141.     // for (int i = 0; i < n; ++i)
  142.     //     for (int j = i+1; j < n; ++j)
  143.     //         for (int k = j+1; k < n; ++k)
  144.     //             if (ccw(point[i], point[j], point[k]) == 0)
  145.     //                 return printf("Three colinear points: %d %d %d\n", i, j, k), 0;
  146.  
  147.     // return 0;
  148.     // sort points by x coordinate
  149.     sort(point.begin(), point.end());
  150.  
  151.     // sequential version of convex hull
  152.     Polygon CHs = convex_hull_sequential();
  153.     puts("Upper Hull (sequential):");
  154.     for (const Point& p: CHs) printf("%d %d\n", p.x, p.y);
  155.     puts("");
  156.  
  157.     // parallel version of convex hull
  158.     Polygon CHp = convex_hull_parallel(0, n-1);
  159.     puts("Upper Hull (parallel):");
  160.     for (const Point& p: CHp) printf("%d %d\n", p.x, p.y);
  161.     puts("");
  162.  
  163.     return 0;
  164. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement