最大土地面积-凸包
题目描述
题解
首先可以发现这四个点必定在凸包上,所以先求出凸包,然后再枚举对角线以及对角线两端到对角线距离最远的点,更新答案即可
代码
#include<bits/stdc++.h>
#define M 2009
using namespace std;
struct point{
double x,y;
point(double a=0,double b=0){x=a,y=b;}
friend inline point operator+(const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
friend inline point operator-(const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
friend inline double operator*(const point &a,const point &b){return a.x*b.y-a.y*b.x;}
friend inline double operator^(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
inline double dist(){return sqrt(x*x+y*y);}
}q[M],p[M];
int n,last;
bool cmp(const point &a,const point &b){
double res=(a-p[1])*(b-p[1]);
if(res) return res>0;
return (a-p[1]).dist()<(b-p[1]).dist();
}
void graham(){
int dat=1;
for(int i=2;i<=n;i++)
if(p[i].x<p[dat].x||p[i].x==p[dat].x&&p[i].y<p[dat].y)
dat=i;
swap(p[dat],p[1]);
sort(p+2,p+n+1,cmp);
q[++last]=p[1];
for(int i=2;i<=n;i++){
while(last>2&&(p[i]-q[last-1])*(q[last]-q[last-1])>=0) last--;
q[++last]=p[i];
}
}
double calc(){
double ans=0.0;
q[0]=q[last];
for(int i=0;i<last;i++){
int p1=i%last,p2=(i+1)%last;
for(int j=i+1;j<last;j++){
while((q[p1+1]-q[i])*(q[j]-q[i])>(q[p1]-q[i])*(q[j]-q[i])) p1=(p1+1)%last;
while((q[j]-q[i])*(q[p2+1]-q[i])>(q[j]-q[i])*(q[p2]-q[i])) p2=(p2+1)%last;
ans=max(ans,(q[p1]-q[i])*(q[j]-q[i])+(q[j]-q[i])*(q[p2]-q[i]));
}
}return ans*1.0/2;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
graham();
printf("%.3lf\n",calc());
return 0;
}