注意事项:

  1. 正着插入一遍,倒着插入一遍,最后还要用 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;
}