BZOJ 1069 [SCOI2007]最大土地面积 ——计算几何

枚举对角线,然后旋转卡壳即可。

#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define eps 1e-8
#define ll long long
#define mp make_pair
 
struct Vector{
    double x,y;
    void print()
    {
        printf("Vector -> (%.3f,%.3f)\n",x,y);
    }
};
 
struct Point{
    double x,y;
    void print()
    {
        printf("Point (%.3f,%.3f)\n",x,y);
    }
};
 
double operator * (Vector a,Vector b)
{return a.x*b.y-a.y*b.x;}
 
Vector operator - (Point a,Point b)
{Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;}
 
int n,top=0;
Point p[2005],sta[2005];
 
bool cmp(Point a,Point b)
{return fabs(a.x-b.x)<eps?a.y<b.y:a.x<b.x;}
 
void Andrew()
{
    sta[++top]=p[1];
    F(i,2,n)
    {
        while (top>=2&&(sta[top]-sta[top-1])*(p[i]-sta[top])<eps) top--;
        sta[++top]=p[i];
    }
    int lower=top;
    D(i,n-1,1)
    {
        while (top-lower>=1&&(sta[top]-sta[top-1])*(p[i]-sta[top])<eps) top--;
        sta[++top]=p[i];
    }
//  printf("In the outside :\n");
//  F(i,1,top) sta[i].print();
}
 
double ans=0;
 
void Rotating()
{
    F(x,1,top-2)
    {
        int a=x%top+1,b=(x+2)%top+1;
        F(y,x+2,top-1)
        {
            while (a%top+1!=y&&(sta[a+1]-sta[x])*(sta[y]-sta[x])>(sta[a]-sta[x])*(sta[y]-sta[x])) a=a%top+1;
            while (b%top+1!=x&&(sta[y]-sta[x])*(sta[b+1]-sta[x])>(sta[y]-sta[x])*(sta[b]-sta[x])) b=b%top+1;
            ans=max(ans,(sta[a]-sta[x])*(sta[y]-sta[x])+(sta[y]-sta[x])*(sta[b]-sta[x]));
        }
    }
}
 
int main()
{
//  freopen("in.txt","r",stdin);
    scanf("%d",&n);
    F(i,1,n) scanf("%lf%lf",&p[i].x,&p[i].y);
    sort(p+1,p+n+1,cmp);
    Andrew();
    Rotating();
    printf("%.3f\n",ans/2.0);
}

  

posted @ 2017-04-09 20:19  SfailSth  阅读(250)  评论(0编辑  收藏  举报