[2018.09.08 T2] 最大土地面积

版权声明:大佬您能赏脸,蒟蒻倍感荣幸,还请联系我让我好好膜拜。 https://blog.csdn.net/ShadyPi/article/details/82531160

暂无链接

最大土地面积

题目描述

在某块平面土地上有 N 个点,你可以选择其中的任意四个点,将这片土地围起来,你可以在这块土地上随意打洞。当然,作为一种沉迷于打洞的动物,你希望这四个点围成的多边形面积最大,以满足你打洞的欲望。

输入说明

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

输出格式

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

样例输入

5
0 0
1 0
1 1
0 1
0.5 0.5

样例输出

1.000

数据规模

对于 30%的数据,4≤N≤500;

对于 100%的数据,4≤N≤2000, |x|,|y|≤100000;

题解

非常裸的旋转卡壳,先求凸包,再在凸包上 O ( n 2 ) 枚举对角线,对对角线两侧各维护一个最大三角形即可。

没想到我这种菜鸡也能在考场上A题。

代码

数据没有凸包为三角形的,为了代码的简介所以删掉了特判。

#include<bits/stdc++.h>
#define db double
#define eps 1e-8
using namespace std;
const int M=2005;
struct sd{db x,y;}pt[M],sta[M];
bool operator <(sd a,sd b){return a.x==b.x?a.y<b.y:a.x<b.x;}
bool operator ==(sd a,sd b){return fabs(a.x-b.x)<eps&&fabs(a.y-b.y)<eps;}
db operator *(sd a,sd b){return a.x*b.y-a.y*b.x;}
sd operator +(sd a,sd b){return (sd){a.x+b.x,a.y+b.y};}
sd operator -(sd a,sd b){return (sd){a.x-b.x,a.y-b.y};}
db area(sd a,sd b,sd c){return fabs((b-a)*(c-a))/2.0;}
int n,top=-1;
db ans;
void in(){scanf("%d",&n);for(int i=1;i<=n;++i)scanf("%lf%lf",&pt[i].x,&pt[i].y);}
void ac()
{
    sort(pt+1,pt+1+n);
    for(int i=1;i<=n;++i){for(;top>0&&(sta[top]-sta[top-1])*(pt[i]-sta[top-1])<eps;--top);sta[++top]=pt[i];}
    for(int k=top,i=n;i>=1;--i){for(;top>k&&(sta[top]-sta[top-1])*(pt[i]-sta[top-1])<eps;--top);sta[++top]=pt[i];}
    for(int i=0,j,le,ri;i<top-3;++i)for(le=i+1,j=i+2,ri=i+3;j<top;++j)
    {
        for(;area(sta[i],sta[le],sta[j])<area(sta[i],sta[le+1],sta[j]);le=(le+1)%top);
        for(;area(sta[i],sta[ri],sta[j])<area(sta[i],sta[ri+1],sta[j]);ri=(ri+1)%top);
        ans=max(ans,area(sta[i],sta[le],sta[j])+area(sta[i],sta[ri],sta[j]));
    }
    printf("%.3lf",ans);
}
int main(){in();ac();}

猜你喜欢

转载自blog.csdn.net/ShadyPi/article/details/82531160
T2