1. 程式人生 > >poj 3348 Cows (求凸包的面積)

poj 3348 Cows (求凸包的面積)

題目連結:poj 3348

題意:給出n個點,問能用這n個點最多能圍成多少面積,一頭牛需要50平方米的地盤,求最多能容納多少頭牛?

題解:直接求這n個點的凸包,最後計算下面積就行了。

 

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>

using namespace std;

const int maxn=10010;

struct point{
    int x,y;
    point(){}
    point(int _x,int _y){
        x=_x;y=_y;
    }
}p[maxn],ch[maxn];

point operator + (point a,point b) {return point(a.x+b.x,a.y+b.y);}
point operator - (point a,point b) {return point(a.x-b.x,a.y-b.y);}
point operator * (point a,int p) { return point(a.x*p,a.y*p);}
point operator / (point a,int p){ return point(a.x/p,a.y/p);}

bool operator < (const point &a,const point &b){
    return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double esp=1e-8;
int dcmp(double x){
    if(fabs(x)<esp) return 0;
    else return x<0?-1:1;
}
bool operator ==(const point &a,const point &b){
    return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;
}

int Cross(point a,point b) { return a.x*b.y-a.y*b.x;}

bool cmp(point a,point b){
    return a.y<b.y||(a.y==b.y&&a.x<b.x);
}

int tot;
void andrew(int n)
{

    sort(p,p+n,cmp);

    tot=-1;
    for(int i=0;i<n;i++) ///構造凸包下側
    {
        while(tot>0&&Cross(ch[tot]-ch[tot-1],p[i]-ch[tot-1])<=0)
            tot--;
        ch[++tot]=p[i];
    }

    for(int i=n-2,k=tot;i>=0;i--){ ///構造凸包上側
        while(tot>k&&Cross(ch[tot]-ch[tot-1],p[i]-ch[tot-1])<=0)
            tot--;
        ch[++tot]=p[i];
    }
}

int Area(point *ch,int n) ///叉積求面積
{
    int area=0;
    for(int i=1;i<n;i++)
        area+=Cross(ch[i]-ch[0],ch[i+1]-ch[0]);
    return area/2;

}


int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        for(int i=0;i<n;i++)
            scanf("%d%d",&p[i].x,&p[i].y);
        andrew(n);

        int item=Area(ch,tot)/50;
        printf("%d\n",item);
    }
}