暂无链接
最大土地面积
题目描述
在某块平面土地上有 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(n2) 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();}