题意:
给你n个点,求将所有点都围起来的凸包的周长
题目链接:传送门
关于凸包的原理:传送门
AC_code:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1e5 + 10, M = 30005, mod = 1e9 + 7, inf = 0x3f3f3f3f;
struct Point {
double x, y;
Point (double x = 0, double y = 0):x(x),y(y) {}
Point operator + (const Point &b) {
return Point(x+b.x, y+b.y);
}
Point operator - (const Point &b) {
return Point(x-b.x,y-b.y);
}
} p[N],res[N];
double dis(Point aa, Point bb) {
return sqrt((aa.x - bb.x) * (aa.x - bb.x) + (aa.y - bb.y) * (aa.y - bb.y));
}
double dot(Point aa, Point bb) {
return aa.x * bb.y - bb.x * aa.y;
}
bool cmp(Point aa, Point bb) {
if(aa.y == bb.y) {
return aa.x < bb.x;
} else {
return aa.y < bb.y;
}
}
int get(Point* p, int n, Point* res) {
sort(p+1, p+1+n, cmp);
res[1] = p[1];
res[2] = p[2];
int top = 2, len;
for(int i = 3; i <= n; i++) {
while(top >= 2 && dot((p[i] - res[top - 1]), (res[top] - res[top-1])) >= 0) {
top--;
}
res[++top] = p[i];
}
len = top;
for(int i = n; i >= 1; i--) {
while(top != len && dot((p[i] - res[top - 1]), (res[top] - res[top-1])) >= 0) {
top--;
}
res[++top] = p[i];
}
return top;
}
int main() {
int n;
while(~scanf("%d", &n)) {
if(n == 0) {
break;
}
for(int i = 1; i <= n; i++) {
scanf("%lf%lf", &p[i].x, &p[i].y);
}
if(n == 1) {
printf("0.00\n");
continue;
} else if(n == 2) {
printf("%.2lf\n",dis(p[1], p[2]));
continue;
}
int m = get(p, n, res);
double tot = 0;
for(int i = 2; i <= m ; i++) {
tot += dis(res[i-1], res[i]);
}
printf("%.2lf\n", tot);
}
return 0;
}