原题链接
题意:给你n个点,求它的凸包面积
解法:经典Andrew算法,不过需要注意当n=2的时候是一条直线,那么计算就是两点之间的距离。n=1答案是0.00,_不然就会喜提wawawa
#include<bits/stdc++.h>
#define ll long long
#define x first
#define y second
using namespace std;
const int maxn = 1e4 + 10;
int n;
double eps = 1e-8;
struct Point{
double x,y;
Point(){}
Point(double a, double b){
x = a;
y = b;
}
};
int dcmp(double x, double y){
if(fabs(x-y)<eps)return 0;
if(x < y)return - 1;
return 1;
}
int sgn(double x){
if(fabs(x) < eps){
return 0;
}
if(x < 0)return -1;
return 1;
}
bool operator == (Point a,Point b){
return sgn(b.x-a.x) == 0 && sgn(b.y-a.y)==0;
}
bool operator < (Point a,Point b){
return sgn(b.y-a.y) == 0 ? sgn(b.x-a.x)<0:b.y<a.y;
}
Point operator - (Point a,Point b){
return Point(b.x-a.x,b.y-a.y);
}
Point operator + (Point a,Point b){
return Point(b.x+a.x,b.y+a.y);
}
double operator *(Point a,Point b){
return b.x*a.x+b.y*a.y;
}
double operator ^(Point a,Point b){
return b.x*a.y-b.y*a.x;
}
Point operator /(double k,Point a){
return Point(a.x/k,a.y/k);
}
double cross(Point A, Point B){
return A.x*B.y-A.y*B.x;
}
int relation(Point a,Point b,Point c){
int d = sgn(cross((b-a),(c-a)));
if(d < 0)return 1;
else if(d > 0)return -1;
return 0;
}
bool cmp(Point a, Point b){
if(a.x == b.x)return a.y < b.y;
return a.x < b.x;
}
double get_dist(Point a, Point b){
double dx = a.x-b.x;
double dy = a.y-b.y;
return sqrt(dx*dx+dy*dy);
}
Point a[maxn];
int stk[maxn];
int top;
bool vis[maxn];
double andrew(){
top = 0;
for(int i = 0; i < n; i++){
while(top >= 2 && relation(a[stk[top - 1]],a[stk[top]],a[i]) <= 0){
if(relation(a[stk[top-1]],a[stk[top]],a[i]) < 0)
vis[stk[top--]] = false;
else top--;
}
stk[++top] = i;
vis[i] = true;
}
vis[0] = false;
for(int i = n-1; i >= 0; i--){
if(vis[i])continue;
while(top >= 2 && relation(a[stk[top-1]],a[stk[top]],a[i]) <= 0){
top--;
}
stk[++top] = i;
}
double ans = 0.0;
for(int i = 2; i <= top; i++){
ans += get_dist(a[stk[i]],a[stk[i - 1]]);
}
return ans;
}
int main(){
while(scanf("%d",&n)!=EOF){
if(n == 0)break;
for(int i = 0; i < n; i++){
double x,y;
scanf("%lf%lf",&x,&y);
a[i] = Point(x,y);
}
sort(a,a+n);
if(n == 1){
printf("0.00\n");
continue;
}
if(n == 2){
double ans = 0.0;
ans = get_dist(a[0],a[1]);
printf("%.2lf\n",ans);
continue;
}
printf("%.2lf\n",andrew());
}
}