原题链接
题意:给你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 ( ) ) ;
}
}