码迷,mamicode.com
首页 > 其他好文 > 详细

P4166 [SCOI2007]最大土地面积

时间:2020-01-17 10:18:21      阅读:71      评论:0      收藏:0      [点我收藏+]

标签:ace   mat   str   name   最大   sort   i+1   class   printf   

题意

显然选的四个点是在凸包上的,我们先求出凸包。

考虑枚举对角线\((i,j)\),发现当\(i\)固定,\(j\)沿逆时针旋转时对角线两端的那两个点时单调的,因此用旋转卡壳维护即可。

code:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2010;
const double eps=1e-8;
int n,top;
double ans;
struct Point
{
    double x,y;
    inline double len(){return sqrt(x*x+y*y);}
    Point operator+(const Point a)const{return (Point){x+a.x,y+a.y};}
    Point operator-(const Point a)const{return (Point){x-a.x,y-a.y};}
    Point operator*(const double k){return (Point){x*k,y*k};}
    Point operator/(const double k){return (Point){x/k,y/k};}
    double operator*(const Point a)const{return x*a.y-y*a.x;}
    double operator&(const Point a)const{return x*a.x+y*a.y;}
}p[maxn],sta[maxn];
inline int dcmp(double x)
{
    if(fabs(x)<=eps)return 0;
    return x<0?-1:1;
}
inline bool cmp(Point a,Point b){return a.x==b.x?a.y<b.y:a.x<b.x;}
inline Point get(Point a,Point b){return b-a;}
inline void build()
{
    sort(p+1,p+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        while(top>1&&dcmp(get(sta[top-1],sta[top])*get(sta[top],p[i]))<=0)top--;
        sta[++top]=p[i];
    }
    int tmp=top;
    for(int i=n-1;i;i--)
    {
        while(top>tmp&&dcmp(get(sta[top-1],sta[top])*get(sta[top],p[i]))<=0)top--;
        sta[++top]=p[i];
    }   
}
inline void solve()
{
    for(int i=1;i<top;i++)p[i-1]=sta[i];
    for(int i=0;i<top-1;i++)
    {
        int a=i+1,b=i+3;
        for(int j=i+2;j<top-1;j++)
        {
            while((a+1)%top!=j&&dcmp(fabs(get(p[i],p[j])*get(p[i],p[(a+1)%top]))-fabs(get(p[i],p[j])*get(p[i],p[a])))>=0)a=(a+1)%top;
            while((b+1)%top!=i&&dcmp(fabs(get(p[i],p[j])*get(p[i],p[(b+1)%top]))-fabs(get(p[i],p[j])*get(p[i],p[b])))>=0)b=(b+1)%top;
            ans=max(ans,fabs(get(p[i],p[j])*get(p[i],p[a]))+fabs(get(p[i],p[j])*get(p[i],p[b])));
        }
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
    build();solve();
    printf("%.3lf",fabs(ans/2.0));
    return 0;
}

P4166 [SCOI2007]最大土地面积

标签:ace   mat   str   name   最大   sort   i+1   class   printf   

原文地址:https://www.cnblogs.com/nofind/p/12204156.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!