bzoj1069: [SCOI2007]最大土地面积

Posted ccz181078

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1069: [SCOI2007]最大土地面积相关的知识,希望对你有一定的参考价值。

Description

  在某块平面土地上有N个点,你可以选择其中的任意四个点,将这片土地围起来,当然,你希望这四个点围成
的多边形面积最大。

Input

  第1行一个正整数N,接下来N行,每行2个数x,y,表示该点的横坐标和纵坐标。

Output

  最大的多边形面积,答案精确到小数点后3位。

选的点都在凸包上且对角线上的点相距最远,所以可以顺序枚举凸包上的点并旋转卡壳
#include<cstdio>
#include<cmath>
#include<algorithm>
typedef long double ld;
const ld _0=1e-7;
struct vec{ld x,y;};
vec operator+(vec a,vec b){return (vec){a.x+b.x,a.y+b.y};}
vec operator-(vec a,vec b){return (vec){a.x-b.x,a.y-b.y};}
vec operator*(vec a,ld x){return (vec){a.x*x,a.y*x};}
ld operator*(vec a,vec b){return a.x*b.y-a.y*b.x;}
bool operator<(vec a,vec b){return a*b>0;}
ld abs(vec a){return sqrt(a.x*a.x+a.y*a.y);}
int n,p,p1,p2,p3;
vec vs[10010],ps[20010],m;
ld ans=0;
int main(){
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        double x,y;
        scanf("%lf%lf",&x,&y);
        vs[i]=(vec){x,y};
    }
    for(int i=1;i<n;i++)if(vs[i].x<vs[p].x||vs[i].x==vs[p].x&&vs[i].y<vs[p].y)p=i;
    m=vs[p];
    for(int i=0;i<n;i++){
        vs[i]=vs[i]-m;
        if(abs(vs[i])<_0)vs[i--]=vs[--n];
    }
    std::sort(vs,vs+n);
    ps[0]=(vec){0,0};
    ps[p=1]=vs[0];
    for(int i=1;i<n;i++){
        while(p&&(ps[p]-ps[p-1])*(vs[i]-ps[p])<_0)--p;
        ps[++p]=vs[i];
    }
    n=p+1;
    for(int i=0;i<=n;i++)ps[i+n]=ps[i];
    int n0=n;
    n=n*2+1;
    for(p=0,p1=p2=p3=1;p<n0;p++){
        while(p2<n&&abs(ps[p2+1]-ps[p])>abs(ps[p2]-ps[p]))++p2;
        if(p2>p3)p3=p2;
        vec w=ps[p2]-ps[p];
        while(p1<n&&w*(ps[p1+1]-ps[p])<w*(ps[p1]-ps[p]))++p1;
        while(p3<n&&w*(ps[p3+1]-ps[p])>w*(ps[p3]-ps[p]))++p3;
        ld S=w*(ps[p3]-ps[p1]);
        if(S>ans)ans=S;
    }
    printf("%.3lf\n",(double)ans*.5);
    return 0;
}

 

以上是关于bzoj1069: [SCOI2007]最大土地面积的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 1069 [SCOI2007]最大土地面积(旋转卡壳)

bzoj1069 SCOI2007 最大土地面积

bzoj1069 [SCOI2007]最大土地面积 旋转卡壳

[BZOJ1069][SCOI2007]最大土地面积 凸包+旋转卡壳

[Bzoj1069][Scoi2007]最大土地面积(凸包)(旋转卡壳)

BZOJ1069: [SCOI2007]最大土地面积