BZOJ1069 SCOI2007最大土地面积(凸包+旋转卡壳)

  求出凸包,显然四个点在凸包上。考虑枚举某点,再移动另一点作为对角线,容易发现剩下两点的最优位置是单调的。过程类似旋转卡壳。

#include<iostream> 
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define N 2010
#define vector point
#define nxt(i) (i%tail+1)
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
    int x=0,f=1;char c=getchar();
    while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    return x*f;
}
int n;
double ans;
const double eps=1E-8;
struct point
{
    double x,y;
    vector operator +(const vector&a) const
    {
        return (vector){x+a.x,y+a.y};
    }
    vector operator -(const vector&a) const
    {
        return (vector){x-a.x,y-a.y};
    }
    double operator *(const vector&a) const
    {
        return x*a.y-y*a.x;
    }
    bool operator <(const point&a) const
    {
        return x<a.x||x==a.x&&y<a.y;
    }
}a[N],b[N];
double area(point x,point z,point y)
{
    return (y-x)*(z-x);
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("bzoj1069.in","r",stdin);
    freopen("bzoj1069.out","w",stdout);
    const char LL[]="%I64d\n";
#else
    const char LL[]="%lld\n";
#endif
    n=read();
    for (int i=1;i<=n;i++) scanf("%lf%lf",&a[i].x,&a[i].y);
    sort(a+1,a+n+1);
    int tail=0;
    for (int i=1;i<=n;i++)
    {
        while (tail>1&&(b[tail]-b[tail-1])*(a[i]-b[tail-1])<eps) tail--;
        b[++tail]=a[i];
    }
    for (int i=n-1;i>=1;i--)
    {
        while (tail>1&&(b[tail]-b[tail-1])*(a[i]-b[tail-1])<eps) tail--;
        b[++tail]=a[i];
    }
    for (int i=1;i<=tail;i++)
    {
        int p=nxt(i),q=nxt(i+2);
        for (int j=i+2;j<=tail;j++)
        {
            while (nxt(p)!=i&&area(b[i],b[j],b[p])<area(b[i],b[j],b[nxt(p)])) p=nxt(p);
            while (nxt(q)!=j&&area(b[i],b[q],b[j])<area(b[i],b[nxt(q)],b[j])) q=nxt(q);
            ans=max(ans,area(b[i],b[j],b[p])+area(b[i],b[q],b[j]));//cout<<area(b[i],b[j],b[p])+area(b[i],b[q],b[j])<<endl; 
        }
    }
    printf("%.3f",ans/2);
    return 0;
}

 

  

 

posted @ 2019-01-20 20:33  Gloid  阅读(170)  评论(0编辑  收藏  举报