Problem id : LOJ 1239
Think in terms of the trivial cases first.For n = 2 ,
For n = 3 ,
Can you guess the formula now?
l1 = dist(point 1,point 3)
l2 = dist(point 2,point 3)
l3 = dist(point 1,point 2)
And we can easily show that arc 1 + arc 2 + arc 3 make 360 degrees and as they are from the same circle .
The answer is sumof(li) + 2*PI*d
For n > 3 ,
So,the idea is to construct a convex hull from the points and find it's perimeter and add 2*PI*d to the answer , and done :-D
Code :
Think in terms of the trivial cases first.For n = 2 ,
For n = 3 ,
Can you guess the formula now?
l1 = dist(point 1,point 3)
l2 = dist(point 2,point 3)
l3 = dist(point 1,point 2)
And we can easily show that arc 1 + arc 2 + arc 3 make 360 degrees and as they are from the same circle .
The answer is sumof(li) + 2*PI*d
For n > 3 ,
So,the idea is to construct a convex hull from the points and find it's perimeter and add 2*PI*d to the answer , and done :-D
Code :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 | // Implementation of Andrew's monotone chain 2D convex hull algorithm. // Asymptotic complexity: O(n log n). // Practical performance: 0.5-1.0 seconds for n=1000000 on a 1GHz machine. #include<bits/stdc++.h> using namespace std; #define PI acos(-1.0) // important constant; alternative #define PI (2.0 * acos(0.0)) typedef double coord_t; // coordinate type typedef double coord2_t; // must be big enough to hold 2*max(|coordinate|)^2 struct Point { coord_t x, y; Point() { this->x = 0.0000000f; this->y = 0.0000000f; } Point(coord_t x,coord_t y) { this->x = x; this->y = y; } bool operator <(const Point &p) const { return x < p.x || (x == p.x && y < p.y); } }; vector<Point>H_global; double dist(Point p1, Point p2) // Euclidean distance { // hypot(dx, dy) returns sqrt(dx * dx + dy * dy) return hypot(p1.x - p2.x, p1.y - p2.y); } // 2D cross product of OA and OB vectors, i.e. z-component of their 3D cross product. // Returns a positive value, if OAB makes a counter-clockwise turn, // negative for clockwise turn, and zero if the points are collinear. coord2_t cross(const Point &O, const Point &A, const Point &B) { return (long)(A.x - O.x) * (B.y - O.y) - (long)(A.y - O.y) * (B.x - O.x); } // Returns a list of points on the convex hull in counter-clockwise order. // Note: the last point in the returned list is the same as the first one. void convex_hull(vector<Point> P) { int n = P.size(), k = 0; vector<Point> H(2*n); // Sort points lexicographically sort(P.begin(), P.end()); // Build lower hull for (int i = 0; i < n; ++i) { while (k >= 2 && cross(H[k-2], H[k-1], P[i]) <= 0) k--; H[k++] = P[i]; } // Build upper hull for (int i = n-2, t = k+1; i >= 0; i--) { while (k >= t && cross(H[k-2], H[k-1], P[i]) <= 0) k--; H[k++] = P[i]; } H.resize(k); for(int a=0; a<H.size(); a++) H_global.push_back(H[a]); } /* //Implementation details vector<Point>in; Point p(-3.4,50); Point p1(33.4,51); Point p2(30.4,15); Point p3(31.4,45); Point p4(3.4,55); Point p5(-33.4,15); Point p6(-31.4,75); in.push_back(p); in.push_back(p1); in.push_back(p2); in.push_back(p3); in.push_back(p4); in.push_back(p5); in.push_back(p6); vector<Point>out = convex_hull(in); for(int a=0;a<out.size();a++) { Point pp = out[a]; cout<<pp.x<<" "<<pp.y<<endl; } */ vector<Point>in; int main() { int T; int cas =0; scanf("%d",&T); while(T--) { int n,d; scanf("%d %d",&n,&d); while(n--) { coord_t x,y; cin>>x>>y; Point p(x,y); in.push_back(p); } convex_hull(in); vector<Point> out_c_h(H_global.begin(),H_global.end()); long double dist_sum = 0.000000000f; if(n==2) { dist_sum += 2*dist(in[0],in[1]); } else for(int a=0; a<out_c_h.size() - 1; a++) { dist_sum += dist(out_c_h[a],out_c_h[a+1]) ; } dist_sum += 2*PI*d; printf("Case %d: %Lf\n",++cas,dist_sum); out_c_h.clear(); in.clear(); H_global.clear(); } return 0; } |
কোন মন্তব্য নেই:
একটি মন্তব্য পোস্ট করুন