尚未完整测试,务必留意模板 bug!

  1. /* Clearink */
  2. #include <cmath>
  3. #include <queue>
  4. #include <cstdio>
  5. #include <vector>
  6. #include <algorithm>
  7. namespace PCG {
  8. const double PI = acos ( -1. ), EPS = 1e-9, INF = 2e9;
  9. /* treat x as 0 <=> -EPS < x < EPS */
  10. inline double dabs ( const double x ) { return x < 0 ? -x : x; }
  11. inline double dmin ( const double a, const double b ) { return a < b ? a : b; }
  12. inline double dmax ( const double a, const double b ) { return b < a ? a : b; }
  13. inline int dcmp ( const double x, const double y = 0 ) {
  14. return dabs ( x - y ) < EPS ? 0 : x < y ? -1 : 1;
  15. }
  16. struct Point {
  17. double x, y;
  18. inline Point ( const double tx = 0, const double ty = 0 ):
  19. x ( tx ), y ( ty ) {}
  20. inline Point operator + ( const Point& p ) const {
  21. return Point ( x + p.x, y + p.y );
  22. }
  23. inline Point operator - ( const Point& p ) const {
  24. return Point ( x - p.x, y - p.y );
  25. }
  26. inline Point operator - () const {
  27. return Point ( -x, -y );
  28. }
  29. inline Point operator * ( const double v ) const {
  30. return Point ( x * v, y * v );
  31. }
  32. inline Point operator / ( const double v ) const {
  33. return Point ( x / v, y / v );
  34. }
  35. inline double operator * ( const Point& p ) const { // dot.
  36. return x * p.x + y * p.y;
  37. }
  38. inline double operator ^ ( const Point& p ) const { // cross.
  39. return x * p.y - y * p.x;
  40. }
  41. inline bool operator == ( const Point& p ) const {
  42. return !dcmp ( x, p.x ) && !dcmp ( y, p.y );
  43. }
  44. inline bool operator != ( const Point& p ) const {
  45. return !( *this == p );
  46. }
  47. inline bool operator < ( const Point& p ) const { // as a pair (x,y).
  48. return dcmp ( x, p.x ) ? x < p.x : y < p.y;
  49. }
  50. inline double length () const { return sqrt ( *this * *this ); }
  51. inline Point unit () const { return *this / this->length (); }
  52. inline Point normal () const { return Point ( y, -x ); }
  53. inline double angle () const { // [0,2pi).
  54. double t = atan2 ( y, x );
  55. return t < 0 ? t + 2 * PI : t;
  56. }
  57. inline Point rotate ( const double alpha ) const {
  58. double c = cos ( alpha ), s = sin ( alpha );
  59. return Point ( x * c - y * s, y * c + x * s );
  60. }
  61. friend inline double angle ( const Point& p, const Point& q ) { // [0,pi).
  62. double t = atan2 ( p ^ q, p * q );
  63. t < 0 && ( t += 2 * PI, 0 );
  64. return t < PI ? t : 2 * PI - t;
  65. }
  66. friend inline double dist ( const Point& p, const Point& q ) {
  67. return ( p - q ).length ();
  68. }
  69. friend inline double slope ( const Point& p, const Point& q ) {
  70. return dcmp ( p.x, q.x ) ?
  71. ( p.y - q.y ) / ( p.x - q.x ) : p.y < q.y ? INF : -INF;
  72. }
  73. inline void read () { scanf ( "%lf %lf", &x, &y ); }
  74. inline void _show ( const char ch = '\n' ) const {
  75. #ifdef RYBY
  76. printf ( "(%f, %f)%c", x, y, ch );
  77. #endif
  78. }
  79. };
  80. typedef Point Vector;
  81. struct Line {
  82. Point p, v;
  83. inline Line (): p (), v () {}
  84. inline Line ( Point a, Point b, const bool type = false ):
  85. p ( a ), v ( type ? b - a : b ) {}
  86. inline Line ( const double a, const double b, const double c ):
  87. p ( dcmp ( a ) ? Point ( -c / a, 0 ) : Point ( 0, -c / b ) ),
  88. v ( -b, a ) {}
  89. inline Point A () const { return p; }
  90. inline Point B () const { return p + v; }
  91. inline bool operator < ( const Line& l ) const {
  92. return dcmp ( atan2 ( v.y, v.x ), atan2 ( l.v.y, l.v.x ) ) < 0;
  93. }
  94. inline bool onLeft ( const Point& q ) const {
  95. return dcmp ( v ^ ( q - p ) ) > 0;
  96. }
  97. inline bool onLine ( const Point& q ) const {
  98. return !dcmp ( ( q - p ) ^ v );
  99. }
  100. inline bool onRay ( const Point& q ) const {
  101. return onLine ( q ) && dcmp ( ( q - p ) * v ) >= 0;
  102. }
  103. inline bool onSegment ( const Point& q ) const {
  104. if ( !onLine ( q ) ) return false;
  105. return dcmp ( ( A () - q ) * ( B () - q ) ) <= 0;
  106. }
  107. friend inline bool sameSide ( const Line& l,
  108. const Point& p, const Point& q ) {
  109. return dcmp ( ( ( p - l.p ) ^ ( p - l.B () ) )
  110. * ( ( q - l.p ) ^ ( q - l.B () ) ) ) > 0;
  111. }
  112. friend inline bool interSegment ( const Line& l1, const Line& l2 ) {
  113. return ( !sameSide ( l1, l2.p, l2.B () ) )
  114. && ( !sameSide ( l2, l1.p, l1.B () ) );
  115. }
  116. friend inline bool interRay ( const Line& l1, const Line& l2 ) {
  117. return dcmp ( ( ( l2.p - l1.p ) ^ l2.v ) / ( l1.v ^ l2.v ) ) > 0
  118. && dcmp ( ( ( l1.p - l2.p ) ^ l1.v ) / ( l2.v ^ l1.v ) ) > 0;
  119. }
  120. friend inline Point lineInter ( const Line& l1, const Line& l2 ) {
  121. return l1.p + l1.v * ( ( l2.p - l1.p ) ^ l2.v ) / ( l1.v ^ l2.v );
  122. }
  123. };
  124. inline std::vector<Point> getConvex ( std::vector<Point> vec,
  125. const bool allowCol ) {
  126. static std::vector<Point> ret;
  127. ret.resize ( vec.size () << 1 );
  128. std::sort ( vec.begin (), vec.end () );
  129. int n = ( int ) vec.size (), top = 0;
  130. for ( int i = 0; i < n; ++i ) {
  131. for ( int d; top > 1; --top ) {
  132. d = dcmp ( ( ret[top - 1] - ret[top - 2] )
  133. ^ ( vec[i] - ret[top - 2] ) );
  134. if ( !( ( !allowCol && d <= 0 ) || ( allowCol && d < 0 ) ) ) break;
  135. }
  136. ret[top++] = vec[i];
  137. }
  138. for ( int tmp = top, i = n - 2; ~i; --i ) {
  139. for ( int d; top > tmp; --top ) {
  140. d = dcmp ( ( ret[top - 1] - ret[top - 2] )
  141. ^ ( vec[i] - ret[top - 2] ) );
  142. if ( !( ( !allowCol && d <= 0 ) || ( allowCol && d < 0 ) ) ) break;
  143. }
  144. ret[top++] = vec[i];
  145. }
  146. if ( n > 1 ) --top;
  147. return ret.resize ( top ), ret;
  148. }
  149. inline bool poleCmp ( const Point& p, const Point& q ) {
  150. static int t;
  151. return ( t = dcmp ( p ^ q ) ) > 0
  152. || ( !t && dcmp ( p.length (), q.length () ) < 0 );
  153. }
  154. inline Point polyCentroid ( const std::vector<Point>& poly ) {
  155. double area = 0; Point ret;
  156. int n = ( int ) poly.size ();
  157. for ( int i = 0; i ^ poly.size (); ++i ) {
  158. double s = poly[i] ^ poly[( i + 1 ) % n];
  159. area += s;
  160. ret.x += ( poly[i].x + poly[( i + 1 ) % n].x ) * s;
  161. ret.y += ( poly[i].y + poly[( i + 1 ) % n].y ) * s;
  162. }
  163. ret.x /= 3, ret.y /= 3; // triangle's centroid.
  164. ret.x /= area, ret.y /= area; // average.
  165. return ret;
  166. }
  167. inline double polyArea ( const std::vector<Point>& poly ) {
  168. double ret = 0; int n = ( int ) poly.size ();
  169. for ( int i = 0; i < n; ++i ) {
  170. ret += poly[i] ^ poly[( i + 1 ) % n];
  171. }
  172. return dabs ( ret / 2 );
  173. }
  174. inline std::vector<Point> halfPlaneInter ( std::vector<Line> lvec ) {
  175. static std::vector<std::pair<double, int> > ord;
  176. static std::deque<Line> que; que.clear ();
  177. static std::deque<Point> ret; ret.clear ();
  178. lvec.push_back ( Line ( Point ( -INF, -INF ), Point ( 1, 0 ) ) );
  179. lvec.push_back ( Line ( Point ( -INF, INF ), Point ( 0, -1 ) ) );
  180. lvec.push_back ( Line ( Point ( INF, -INF ), Point ( 0, 1 ) ) );
  181. lvec.push_back ( Line ( Point ( INF, INF ), Point ( -1, 0 ) ) );
  182. int n = ( int ) lvec.size (); ord.resize ( n );
  183. for ( int i = 0; i < n; ++i ) {
  184. ord[i].first = atan2 ( lvec[i].v.y, lvec[i].v.x );
  185. ord[i].second = i;
  186. }
  187. std::sort ( ord.begin (), ord.end () );
  188. que.push_back ( lvec[ord[0].second] );
  189. for ( int i = 1; i < n; ++i ) {
  190. const Line& l ( lvec[ord[i].second] );
  191. for ( ; que.size () > 1 && !l.onLeft ( ret.back () );
  192. que.pop_back (), ret.pop_back () );
  193. for ( ; que.size () > 1 && !l.onLeft ( ret[0] );
  194. que.pop_front (), ret.pop_front () );
  195. if ( dcmp ( l.v ^ que.back ().v ) ) {
  196. que.push_back ( l );
  197. if ( que.size () > 1 ) {
  198. ret.push_back (
  199. lineInter ( que[que.size () - 2], que.back () ) );
  200. }
  201. } else if ( que.back ().onLeft ( l.p ) ) {
  202. que.back () = l;
  203. if ( que.size () > 1 ) {
  204. ret.back () = lineInter ( que[que.size () - 2], que.back () );
  205. }
  206. }
  207. }
  208. for ( ; que.size () > 1 && !que[0].onLeft ( ret.back () );
  209. que.pop_back (), ret.pop_back () );
  210. if ( que.size () <= 2 ) return {};
  211. if ( que.size () > 1 ) ret.push_back ( lineInter ( que[0], que.back () ) );
  212. return std::vector<Point> ( ret.begin (), ret.end () );
  213. }
  214. inline double convexDiameter ( const std::vector<Point>& conv ) {
  215. int n = ( int ) conv.size ();
  216. if ( n == 1 ) return 0;
  217. if ( n == 2 ) return dist ( conv[0], conv[1] );
  218. double ret = 0;
  219. for ( int i = 0, j = 2; i < n; ++i ) {
  220. for ( ; dabs ( ( conv[j] - conv[i] )
  221. ^ ( conv[( i + 1 ) % n] - conv[i] ) )
  222. < dabs ( ( conv[( j + 1 ) % n] - conv[i] )
  223. ^ ( conv[( i + 1 ) % n] - conv[i] ) ); j = ( j + 1 ) % n );
  224. ret = dmax ( ret, dmax ( dist ( conv[i], conv[j] ),
  225. dist ( conv[( i + 1 ) % n], conv[j] ) ) );
  226. }
  227. return ret;
  228. }
  229. inline int findPole ( const std::vector<Point>& vec ) {
  230. int ret = -1, n = ( int ) vec.size ();
  231. for ( int i = 0; i < n; ++i ) {
  232. if ( !~ret || dcmp ( vec[ret].y, vec[i].y ) > 0
  233. || ( !dcmp ( vec[ret].y, vec[i].y )
  234. && dcmp ( vec[ret].x, vec[i].x ) > 0 ) ) {
  235. ret = i;
  236. }
  237. }
  238. return ret;
  239. }
  240. inline void getPoleOrdered ( std::vector<Point>& conv ) {
  241. int pid = findPole ( conv ), n = ( int ) conv.size ();
  242. pid = n - pid - 1; // reversed.
  243. std::reverse ( conv.begin (), conv.end () );
  244. std::reverse ( conv.begin (), conv.begin () + pid + 1 );
  245. std::reverse ( conv.begin () + pid + 1, conv.end () );
  246. }
  247. inline std::vector<Point> convexSum ( std::vector<Point> A,
  248. std::vector<Point> B ) {
  249. static std::vector<Point> ret; ret.clear ();
  250. getPoleOrdered ( A ), getPoleOrdered ( B );
  251. // if use `getConvexG`, there's no need to `getPoleOrdered`.
  252. int n = ( int ) A.size (), m = ( int ) B.size ();
  253. Point ap ( A[0] ), bp ( B[0] );
  254. ret.push_back ( ap + bp );
  255. for ( int i = 0; i < n - 1; ++i ) A[i] = A[i + 1] - A[i];
  256. A[n - 1] = ap - A[n - 1];
  257. for ( int i = 0; i < m - 1; ++i ) B[i] = B[i + 1] - B[i];
  258. B[m - 1] = bp - B[m - 1];
  259. int i = 0, j = 0;
  260. while ( i < n && j < m ) {
  261. ret.push_back ( ret.back ()
  262. + ( dcmp ( A[i] ^ B[j] ) >= 0 ? A[i++] : B[j++] ) );
  263. }
  264. for ( ; i < n; ret.push_back ( ret.back () + A[i++] ) );
  265. for ( ; j < m; ret.push_back ( ret.back () + B[j++] ) );
  266. return ret;
  267. }
  268. } using namespace PCG;
  269. int n;
  270. std::vector<Point> pos, cnv;
  271. int main () {
  272. /*
  273. example: https://www.luogu.com.cn/problem/P2742
  274. */
  275. scanf ( "%d", &n ), pos.resize ( n );
  276. for ( int i = 0; i < n; ++i ) pos[i].readn ();
  277. cnv = getConvex ( pos, true ); // also, it could be `getConvex ( pos, false )`.
  278. #ifdef RYBY
  279. for ( auto p: cnv ) p._show ( ' ' );
  280. putchar ( '\n' );
  281. #endif
  282. int s = cnv.size ();
  283. double ans = 0;
  284. for ( int i = 0; i < s; ++i ) {
  285. ans += dist ( cnv[i], cnv[( i + 1 ) % s] );
  286. }
  287. printf ( "%.2f\n", ans );
  288. return 0;
  289. }
  290. /*
  291. try this data:
  292. 5
  293. 0 0
  294. 0 3
  295. 1 2
  296. 2 1
  297. 3 0
  298. */



  大概是壬寅年新版本。(

  1. /*+Rainybunny+*/
  2. // #include <bits/stdc++.h>
  3. #include <cmath>
  4. #include <queue>
  5. #include <cstdio>
  6. #include <vector>
  7. #include <cassert>
  8. #include <iostream>
  9. #include <algorithm>
  10. #define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
  11. #define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
  12. namespace ComputingGeometry {
  13. const double EPS = 1e-9, PI = acos(-1.), DINF = 1e18;
  14. template <typename Tp>
  15. inline void chkmin(Tp& u, const Tp& v) { v < u && (u = v, 0); }
  16. template <typename Tp>
  17. inline void chkmax(Tp& u, const Tp& v) { u < v && (u = v, 0); }
  18. template <typename Tp>
  19. inline Tp imin(const Tp& u, const Tp& v) { return u < v ? u : v; }
  20. template <typename Tp>
  21. inline Tp imax(const Tp& u, const Tp& v) { return u < v ? v : u; }
  22. template <typename Tp>
  23. inline Tp iabs(const Tp& u) { return u < 0 ? -u : u; }
  24. inline int sign(const double x) { return iabs(x) <= EPS ? 0 : x < 0 ? -1 : 1; }
  25. struct Point {
  26. double x, y;
  27. Point(): x(0.), y(0.) {}
  28. Point(const double u, const double v): x(u), y(v) {}
  29. inline void read() { scanf("%lf %lf", &x, &y); }
  30. inline Point operator + (const Point& p) const {
  31. return { x + p.x, y + p.y };
  32. }
  33. inline Point operator - () const { return { -x, -y }; }
  34. inline Point operator - (const Point& p) const {
  35. return { x - p.x, y - p.y };
  36. }
  37. inline Point operator * (const double k) const {
  38. return { k * x, k * y };
  39. }
  40. inline Point operator / (const double k) const {
  41. return { x / k, y / k };
  42. }
  43. inline bool operator == (const Point& p) const {
  44. return !sign(x - p.x) && !sign(y - p.y);
  45. }
  46. inline bool operator != (const Point& p) const {
  47. return !(*this == p);
  48. }
  49. inline double operator * (const Point& p) const {
  50. return x * p.x + y * p.y;
  51. }
  52. inline double operator ^ (const Point& p) const {
  53. return x * p.y - y * p.x;
  54. }
  55. inline double leng() const { return sqrt(*this * *this); }
  56. friend inline double dist(const Point& u, const Point& v) {
  57. return (u - v).leng();
  58. }
  59. inline Point norm() const { return { -y, x }; }
  60. inline double angle() const {
  61. double ret = atan2(y, x);
  62. if (ret < 0) ret += 2 * PI;
  63. return ret;
  64. }
  65. friend inline double angle(const Point& u, const Point& v) {
  66. double ret = v.angle() - u.angle();
  67. if (ret > PI) ret -= 2 * PI;
  68. if (ret < -PI) ret += 2 * PI;
  69. return ret;
  70. }
  71. inline Point rotate(const double alp) const {
  72. double ca = cos(alp), sa = sin(alp);
  73. return { x * ca - y * sa, x * sa + y * ca };
  74. }
  75. inline bool operator < (const Point& p) const {
  76. return !sign(x - p.x) ? y < p.y : x < p.x;
  77. }
  78. };
  79. typedef Point Vector;
  80. typedef std::vector<Point> Polygon;
  81. typedef Polygon Convex;
  82. struct Ray {
  83. Point p, v;
  84. Ray() {}
  85. Ray(const Point& a, const Point& b, const bool type = true) {
  86. if (type) p = a, v = b - a;
  87. else p = a, v = b;
  88. }
  89. Ray(const double a, const double b, const double c):
  90. p(sign(a) ? Point(-c / a, 0) : Point(0, -c / b)), v(-b, a) {}
  91. inline Point st() const { return p; }
  92. inline Point ed() const { return p + v; }
  93. inline void readSeg() {
  94. scanf("%lf %lf %lf %lf", &p.x, &p.y, &v.x, &v.y);
  95. v = v - p;
  96. }
  97. friend inline bool isInterSeg(const Ray& a, const Ray& b) { // *
  98. return imin(a.st().x, a.ed().x) <= imax(b.st().x, b.ed().x)
  99. && imax(a.st().x, a.ed().x) <= imin(b.st().x, b.ed().x)
  100. && imin(a.st().y, a.ed().y) <= imax(b.st().y, b.ed().y)
  101. && imax(a.st().y, a.ed().y) <= imin(b.st().y, b.ed().y)
  102. && sign(a.v ^ (b.st() - a.st())) * sign(a.v ^ (b.ed() - a.st())) <=0
  103. && sign(b.v ^ (a.st() - b.st())) * sign(b.v ^ (a.ed() - b.st())) <=0;
  104. }
  105. friend inline Point lineInter(const Ray& a, const Ray& b) {
  106. return a.p + a.v * ((b.p - a.p) ^ b.v) / (a.v ^ b.v);
  107. }
  108. friend inline double pSegDist(const Point& p, const Ray& s) {
  109. if (sign(s.v * (p - s.p)) < 0) return dist(p, s.p);
  110. if (sign(-s.v * (p - s.ed())) < 0) return dist(p, s.ed());
  111. return iabs(s.v ^ (p - s.p)) / s.v.leng();
  112. }
  113. friend inline double sSegDist(const Ray& s, const Ray& t) {
  114. return imin(imin(pSegDist(s.st(), t), pSegDist(s.ed(), t)),
  115. imin(pSegDist(t.st(), s), pSegDist(t.ed(), s)));
  116. }
  117. };
  118. typedef Ray Line;
  119. typedef Ray Segment;
  120. typedef std::vector<Line> PlaneCut;
  121. inline Convex getConvex(Polygon P, const bool allw = false) {
  122. int n = int(P.size()), top = 0, tmp; Convex ret(n << 1);
  123. std::sort(P.begin(), P.end());
  124. for (Point& p: P) {
  125. for (int s; top > 1; --top) {
  126. s = sign((ret[top - 1] - ret[top - 2]) ^ (p - ret[top - 2]));
  127. if (s - !allw >= 0) break;
  128. }
  129. ret[top++] = p;
  130. }
  131. std::reverse(P.begin(), P.end()), tmp = top;
  132. for (Point& p: P) {
  133. for (int s; top > tmp; --top) {
  134. s = sign((ret[top - 1] - ret[top - 2]) ^ (p - ret[top - 2]));
  135. if (s - !allw >= 0) break;
  136. }
  137. ret[top++] = p;
  138. }
  139. if (n > 1) --top;
  140. return ret.resize(top), ret;
  141. }
  142. inline double getArea(const Polygon& P) {
  143. double ret = 0.; int n = int(P.size());
  144. rep (i, 0, n - 1) ret += P[i] ^ P[(i + 1) % n];
  145. return iabs(ret) * 0.5;
  146. }
  147. inline std::pair<Point, Point> convexDiameter(const Convex& C) {
  148. int n = int(C.size());
  149. if (n == 1) return { C[0], C[0] };
  150. if (n == 2) return { C[0], C[1] };
  151. double dia = 0.; std::pair<Point, Point> ans;
  152. for (int i = 0, j = 1; i < n; ++i) {
  153. while (((C[(i + 1) % n] - C[i]) ^ (C[j] - C[i]))
  154. < ((C[(i + 1) % n] - C[i]) ^ (C[(j + 1) % n] - C[i])))
  155. j = (j + 1) % n;
  156. double d1 = dist(C[i], C[j]), d2 = dist(C[(i + 1) % n], C[j]);
  157. if (d1 > dia) dia = d1, ans = { C[i], C[j] };
  158. if (d2 > dia) dia = d2, ans = { C[(i + 1) % n], C[j] };
  159. }
  160. return ans;
  161. }
  162. inline double convicesDist(const Convex& A, const Convex& B) {
  163. int n = int(A.size()), m = int(B.size()), p = 0, q = 0;
  164. rep (i, 1, n - 1) if (A[i].y < A[p].y) p = i;
  165. rep (i, 1, m - 1) if (B[i].y > B[q].y) q = i;
  166. double ret = 1e100;
  167. rep (i, 0, n - 1) {
  168. while (sign((A[(p + 1) % n] - A[p]) ^ (B[(q + 1) % m] - B[q])) > 0)
  169. q = (q + 1) % m;
  170. chkmin(ret, sSegDist(Ray(A[p], A[(p + 1) % n]),
  171. Ray(B[q], B[(q + 1) % m])));
  172. p = (p + 1) % n;
  173. }
  174. return ret;
  175. }
  176. inline Convex halfPlaneInter(PlaneCut& vec, const bool apd = false) {
  177. if (apd) {
  178. vec.push_back(Ray(Point(-DINF, -DINF), Point(1, 0), 0));
  179. vec.push_back(Ray(Point(DINF, -DINF), Point(0, 1), 0));
  180. vec.push_back(Ray(Point(DINF, DINF), Point(-1, 0), 0));
  181. vec.push_back(Ray(Point(-DINF, DINF), Point(0, -1), 0));
  182. }
  183. int n = int(vec.size());
  184. std::vector<double> pol(n); std::vector<int> ord(n);
  185. rep (i, 0, n - 1) ord[i] = i, pol[i] = atan2(vec[i].v.y, vec[i].v.x);
  186. std::sort(ord.begin(), ord.end(),
  187. [&](const int u, const int v)->bool {
  188. return sign(pol[u] - pol[v]) ? pol[u] < pol[v]
  189. : (vec[v].v ^ (vec[u].p - vec[v].p)) > 0;
  190. }
  191. );
  192. std::vector<int> tmp; tmp.push_back(ord[0]);
  193. rep (i, 1, n - 1) {
  194. if (sign(pol[ord[i]] - pol[ord[i - 1]])) {
  195. tmp.push_back(ord[i]);
  196. }
  197. }
  198. ord.swap(tmp), n = ord.size();
  199. std::deque<Line> deq;
  200. deq.push_back(vec[ord[0]]), deq.push_back(vec[ord[1]]);
  201. std::deque<Point> pnt;
  202. pnt.push_back(lineInter(deq.front(), deq.back()));
  203. rep (i, 2, n - 1) {
  204. Line& l(vec[ord[i]]);
  205. while (deq.size() > 1 && sign(l.v ^ (pnt.back() - l.p)) <= 0)
  206. deq.pop_back(), pnt.pop_back();
  207. while (deq.size() > 1 && sign(l.v ^ (pnt.front() - l.p)) <= 0)
  208. deq.pop_front(), pnt.pop_front();
  209. pnt.push_back(lineInter(deq.back(), l));
  210. deq.push_back(l);
  211. }
  212. while (deq.size() > 1
  213. && sign(deq.front().v ^ (pnt.back() - deq.front().p)) < 0)
  214. deq.pop_back(), pnt.pop_back();
  215. while (deq.size() > 1
  216. && sign(deq.back().v ^ (pnt.front() - deq.back().p)) < 0)
  217. deq.pop_front(), pnt.pop_front();
  218. if (apd) rep (i, 0, 3) vec.pop_back();
  219. if (deq.size() <= 2) return Convex();
  220. pnt.push_back(lineInter(deq.front(), deq.back()));
  221. while (pnt.size() > 1 && pnt.front() == pnt.back()) pnt.pop_back();
  222. std::vector<Point> ret; ret.push_back(pnt[0]);
  223. rep (i, 1, int(pnt.size()) - 1) {
  224. if (pnt[i] != pnt[i - 1]) {
  225. ret.push_back(pnt[i]);
  226. }
  227. }
  228. return ret;
  229. }
  230. } using namespace ComputingGeometry;
  231. int main() {
  232. int n; scanf("%d", &n);
  233. PlaneCut L;
  234. while (n--) {
  235. int m; scanf("%d", &m); Polygon P(m);
  236. for (auto& p: P) p.read();
  237. rep (i, 0, m - 1) L.push_back(Ray(P[i], P[(i + 1) % m]));
  238. }
  239. printf("%.3f\n", getArea(halfPlaneInter(L)));
  240. return 0;
  241. }

Note -「计算几何」模板的更多相关文章

  1. Note -「多项式」基础模板(FFT/NTT/多模 NTT)光速入门

      进阶篇戳这里. 目录 何为「多项式」 基本概念 系数表示法 & 点值表示法 傅里叶(Fourier)变换 概述 前置知识 - 复数 单位根 快速傅里叶正变换(FFT) 快速傅里叶逆变换(I ...

  2. 「BJWC2010」模板严格次小生成树

    题目描述 小 \(C\) 最近学了很多最小生成树的算法,\(Prim\) 算法.\(Kruskal\) 算法.消圈算法等等.正当小\(C\)洋洋得意之时,小\(P\)又来泼小\(C\)冷水了.小\(P ...

  3. Note -「群论」学习笔记

    目录 前置知识 群 置换 Burnside 引理与 Pólya 定理 概念引入 引例 轨道-稳定子(Orbit-Stabilizer)定理 证明 Burnside 引理 证明 Pólya 定理 证明 ...

  4. Note -「线性规划」学习笔记

    \(\mathcal{Definition}\)   线性规划(Linear Programming, LP)形式上是对如下问题的描述: \[\operatorname{maximize}~~~~z= ...

  5. Solution -「LOCAL」模板

    \(\mathcal{Description}\)   OurOJ.   给定一棵 \(n\) 个结点树,\(1\) 为根,每个 \(u\) 结点有容量 \(k_u\).\(m\) 次操作,每次操作 ...

  6. Note -「模拟退火」

    随机化算法属于省选芝士体系 0x01 前置芝士 你只需要会 rand 就可以啦! 当然如果你想理解的更透彻也可以先看看 爬山算法 0x02 关于退火 退火是一种金属热处理工艺,指的是将金属缓慢加热到一 ...

  7. 「luogu3380」【模板】二逼平衡树(树套树)

    「luogu3380」[模板]二逼平衡树(树套树) 传送门 我写的树套树--线段树套平衡树. 线段树上的每一个节点都是一棵 \(\text{FHQ Treap}\) ,然后我们就可以根据平衡树的基本操 ...

  8. 「luogu3402」【模板】可持久化并查集

    「luogu3402」[模板]可持久化并查集 传送门 我们可以用一个可持久化数组来存每个节点的父亲. 单点信息更新和查询就用主席树多花 一个 \(\log\) 的代价来搞. 然后考虑如何合并两个点. ...

  9. SpringBoot图文教程10—模板导出|百万数据Excel导出|图片导出「easypoi」

    有天上飞的概念,就要有落地的实现 概念十遍不如代码一遍,朋友,希望你把文中所有的代码案例都敲一遍 先赞后看,养成习惯 SpringBoot 图文教程系列文章目录 SpringBoot图文教程1「概念+ ...

随机推荐

  1. Java 私有接口 【类中嵌套接口】

    1.前言 接口十分常用,能规范实现类的命名 和 实现多个实现类的向上转型成统一类型 ,但是接口的修饰符只能是 public吗? 当然不是,可以是private , 难道是像这样? 显然不可以,已经报错 ...

  2. 访问 远程 tomcat 的管理页面 /manager/html 提示 403 的具体解决操作

    1.前言 我在阿里云服务器放了个tomcat ,启动后 ,访问 /manager/html提示403无权访问 原因是 tomcat默认仅仅允许本地的浏览器访问,有ip限制 需要将ip限制去除 顺便把账 ...

  3. JAVA自定义连接池原理设计(一)

    一,概述 本人认为在开发过程中,需要挑战更高的阶段和更优的代码,虽然在真正开发工作中,代码质量和按时交付项目功能相比总是无足轻重.但是个人认为开发是一条任重而道远的路.现在本人在网上找到一个自定义连接 ...

  4. 【Java】代码块

    代码块 代码块的作用:用来初始化类.对象 代码块如果有修饰的话,只能使用static 分类:静态代码块.非静态代码块 静态代码块 static{ } 内部可以有输出语句 随着类的加载而执行,而且只执行 ...

  5. 《剑指offer》面试题60. n个骰子的点数

    问题描述 把n个骰子扔在地上,所有骰子朝上一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率. 你需要用一个浮点数数组返回答案,其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i ...

  6. Solon Web 开发,五、数据访问、事务与缓存应用

    Solon Web 开发 一.开始 二.开发知识准备 三.打包与运行 四.请求上下文 五.数据访问.事务与缓存应用 六.过滤器.处理.拦截器 七.视图模板与Mvc注解 八.校验.及定制与扩展 九.跨域 ...

  7. 多种语言tcp编程

    再次强调,最好socket编程 c#的tcpclient等封装无法对接android的socket服务器 c#的tcpclient等封装可对接java的socket服务器 python socket服 ...

  8. gin源码解读2-揭开gin的神秘面纱

    数据如何在gin中流转 func main() { gin.SetMode(gin.DebugMode) // 设置为开发模式 router := gin.Default() _ = router.S ...

  9. java匿名内部类-细节

    1 package face_09; 2 3 public class InnerClassDemo50 { 4 static class Inner{ 5 6 } 7 public static v ...

  10. python 统计工作簿中每个人名出现的次数

    工作簿 需求:统计人名出现的次数 代码: # coding=gbk import pandas as pd import re def extract_chinese(txt): pattern = ...