【bzoj 1069】最大土地面积(旋转卡壳)

来源:互联网 发布:销售清单软件免费 编辑:程序博客网 时间:2024/06/05 06:37

传送门biu~
枚举一条对角线,在对角线两端分别求最大三角形,旋转卡壳。

#include<bits/stdc++.h>using namespace std;int tp,n;struct point{    double x,y;    point() {}    point(double _,double __){x=_;y=__;}    }p[2005],s[2005];double dis(point a,point b){return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);}point operator-(point a,point b){return point(a.x-b.x,a.y-b.y);}double operator*(point a,point b){return a.x*b.y-a.y*b.x;}bool operator<(point a,point b){    double tmp=(a-p[1])*(b-p[1]);    return tmp<0 || (tmp==0 && dis(a,p[1])<dis(b,p[1]));}void solve(){    int k=1;    for(int i=2;i<=n;++i)        if(p[k].y>p[i].y||(p[k].y==p[i].y&&p[k].x)>p[i].x)  k=i;    swap(p[1],p[k]);    sort(p+2,p+n+1);    for(int i=1;i<=n;++i){        while(tp>1 && (p[i]-s[tp-1])*(s[tp]-s[tp-1])<=0)    --tp;        s[++tp]=p[i];    }}double calc(){    s[tp+1]=p[1];    double re=0;    int a,b;    for(int i=1;i<=tp;++i){        a=i%tp+1;b=(i+2)%tp+1;        for(int j=i+2;j<=tp;++j){            while(a%tp+1!=j && (s[j]-s[i])*(s[a+1]-s[i])>(s[j]-s[i])*(s[a]-s[i]))   a=a%tp+1;            while(b%tp+1!=i && (s[b+1]-s[i])*(s[j]-s[i])>(s[b]-s[i])*(s[j]-s[i]))   b=b%tp+1;            re=max(re,(s[j]-s[i])*(s[a]-s[i])+(s[b]-s[i])*(s[j]-s[i]));        }    }    return re;}int main(){    scanf("%d",&n);    for(int i=1;i<=n;++i)   scanf("%lf%lf",&p[i].x,&p[i].y);    solve();    printf("%.3lf",calc()/2);    return 0;}
阅读全文
0 0
原创粉丝点击