首页 > 代码库 > 凸边形外壳

凸边形外壳

凸边形外壳

Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 27   Accepted Submission(s) : 4

Font: Times New Roman | Verdana | Georgia

Font Size:  

Problem Description

Maxwell is a naughty boy. 
One day, he fouled the white and clean wall with ink. Since his mother will come back home soon, Maxwell wanted to find a white convex polygon to cover these ink drops. Could you tell him the minimal area of the convex polygon which can cover all the ink drops?
Now, given the coordinates of these ink drops, you will answer the minimal area of the convex polygon that can cover all the ink drops.

Input

The first line of the input is a positive integer T. T is the number of the test cases followed. 
The first line of each test case is a positive integer N (0<N<=10^5). N is the number of the ink drops. After that, N lines are followed. The ith line contains two integers Xi and Yi (0<=Xi, Yi<20000) which tell you the coordinate of the ith ink drops. There may be one or more spaces between these integers.

Output

The output of the program should consist of one line of output for each test case. The output of each test case only contains the minimal area of the convex polygon. The area is a real number that has one digit after the decimal point. No redundant spaces are needed.

Sample Input

2
4
0 0
1 0
0 1
1 1
2
0 0
0 1

Sample Output

1.0
0.0

Author

HYNU


题意是说给定一些点求包含这些点的最小凸边形面积,直接套用模板做的。。。

#include <iostream> 
#include <cmath> 
#include <algorithm> 
#include <cstdio> 
using namespace std; 
#define MAX 100002 
#define eps 1e-9 
int n,cnt; 
 
struct Point 

    double x,y; 
    Point (){} 
    Point ( double x, double y ) : x(x) , y(y) {} 
}p[MAX],ch[MAX]; 
typedef Point Vector; 
Point operator - ( Point a , Point b ) { return Point ( a.x - b.x , a.y - b.y ); } 
 
bool cmp ( Point a , Point b )  //将每个点通过优先x最小然后y最小的顺序来排序 

    if ( a.x != b.x ) return a.x < b.x; 
    else return a.y < b.y; 

 
int dcmp ( double x ) 

    if ( fabs ( x ) < eps ) return 0; 
    else return x < 0 ? -1 : 1; 

 
double Cross ( Vector u , Vector v )  //叉乘 

    return u.x * v.y - u.y * v.x; 

 
int ConvexHull ( Point *p , Point *ch )  //求凸包Andrew算法 

    sort ( p , p + n , cmp );   
    int m = 0; 
    for ( int i = 0 ; i < n ; i ++ ) 
    { 
        while ( m > 1 && dcmp ( Cross ( ch[m-1] - ch[m-2] , p[i] - ch[m-2] ) ) <= 0 ) m--; 
        ch[m++] = p[i]; 
    } 
    int k = m; 
    for ( int i = n - 2 ; i >= 0 ; i -- ) 
    { 
        while ( m > k && dcmp ( Cross ( ch[m-1] - ch[m-2] , p[i] - ch[m-2] ) ) <= 0 ) m --; 
        ch[m++] = p[i]; 
    } 
    return m; 

 
double PolygonArea ( Point *ch )  //求多边形面积(因为是凸包所以它的有向面积就是它本身的面积 

    double area = 0; 
    for ( int i = 1 ; i < cnt -1 ; i ++ ) 
    { 
        area += Cross ( ch[i] - ch[0] , ch[i+1] - ch[0] ); 
        //cout << area << endl; 
    } 
    return area / 2.0; 

 
int main() 

int t;
scanf("%d",&t);
while ( t-- ){
    scanf ( "%d" , &n ); 
    for( int i = 0 ; i < n ; i ++ ) 
        scanf ( "%lf%lf" , &p[i].x , &p[i].y ); 
    cnt = ConvexHull ( p , ch ); 
    printf ( "%.1lf\n" , PolygonArea( ch ) ); 
}
    return 0;