注意事项:
- 正着插入一遍,倒着插入一遍,最后还要用 1 号点弹一下栈顶。
代码:
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
| int n; Point a[MAXn + 10];
int bottomc, cntc, c[MAXn + 10]; bool inc[MAXn + 10]; inline void pop(int id) { while (cntc > bottomc && sig((a[c[cntc - 1]] >> a[c[cntc]]) & (a[c[cntc]] >> a[id])) <= 0) { inc[c[cntc]] = 0; --cntc; } } inline void push(int id) { inc[id] = 1; c[++cntc] = id; } void evaconv() { bottomc = 1; cntc = 0; sort(a + 1, a + 1 + n); for (int i = 1; i <= n; ++i) { pop(i); push(i); } bottomc = cntc; for (int i = n; i; --i) { if (inc[i]) continue; pop(i); push(i); } pop(1); }
|
Luogu P2742 [USACO5.1]圈奶牛Fencing the Cows /【模板】二维凸包
代码:
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
| #include<bits/stdc++.h> using namespace std; const int MAXn = 1e5;
template <typename T> inline void read(T &a) { char c;for (c = getchar(); (c < '0' || c > '9') && c != '-'; c = getchar());bool f = c == '-';T x = f ? 0 : (c ^ '0');for (c = getchar(); c >= '0' && c <= '9'; c = getchar()) {x = x * 10 + (c ^ '0');}a = f ? -x : x; } template <typename T, typename ...Argv> inline void read(T &a, Argv &...argv) { read(a), read(argv...); }
const double EPS = 1e-8; inline int sig(double x) { if (x < -EPS) return -1; else if (x > EPS) return 1; else return 0; } struct Point { double x, y; inline Point operator>>(Point sec) {return Point{sec.x - x, sec.y - y};} inline double operator*(Point sec) {return x * sec.x + y * sec.y;} inline double operator&(Point sec) {return x * sec.y - y * sec.x;} inline bool operator<(const Point sec) const { if (x != sec.x) return x < sec.x; else return y < sec.y; } }; inline double length(Point a) { return sqrt(a * a); }
int n; Point a[MAXn + 10];
int bottomc, cntc, c[MAXn + 10]; bool inc[MAXn + 10]; inline void pop(int id) { while (cntc > bottomc && sig((a[c[cntc - 1]] >> a[c[cntc]]) & (a[c[cntc]] >> a[id])) <= 0) { inc[c[cntc]] = 0; --cntc; } } inline void push(int id) { inc[id] = 1; c[++cntc] = id; } void evaconv() { bottomc = 1; cntc = 0; sort(a + 1, a + 1 + n); for (int i = 1; i <= n; ++i) { pop(i); push(i); } bottomc = cntc; for (int i = n; i; --i) { if (inc[i]) continue; pop(i); push(i); } pop(1); }
signed main() { read(n); for (int i = 1; i <= n; ++i) { scanf("%lf%lf", &a[i].x, &a[i].y); } evaconv(); double ans = 0; for (int i = 1; i < cntc; ++i) { ans += length(a[c[i]] >> a[c[i + 1]]); } ans += length(a[c[cntc]] >> a[c[1]]); printf("%.2lf\n", ans); return 0; }
|