准备开始BZOJ补完计划了。
话说终于可以切计算几何了,好开森。
虽然这题确实很简单。。。。。
第一眼就看出来 凸包+旋转卡壳没跑了。
先求凸包。
然后在旋转卡壳的时候,每次求出一对对踵点,在连线的左侧和右侧各找一个最远点,四个点构成的可能是最大面积,求一下更新。
具体证明什么的??????
不会(。・_・。)ノ
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const double eps=1e-8;
int dcmp(double x){
if(fabs(x)<eps)return 0;
return x<0?-1:1;
}
struct point{
double x,y;
};
bool cmp(point a,point b){
if(!dcmp(a.x-b.x))return a.y<b.y;
return a.x<b.x;
}
typedef point vector;
vector operator-(point a,point b){
return (vector){a.x-b.x,a.y-b.y};
}
double cross(vector a,vector b){
return a.x*b.y-a.y*b.x;
}
double cross(point a,point b,point c){
return cross(b-a,c-a);
}
double sqr(double x){return x*x;}
double dist(point a,point b){
return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));
}
struct ConvexHull{
point ch[2005];
int m;
void andrew(point *p,int n){
sort(p+1,p+1+n,cmp);
m=0;
for(int i=1;i<=n;i++){
while(m>1&&cross(ch[m-2],ch[m-1],p[i])<=0)m--;
ch[m++]=p[i];
}
int k=m;
for(int i=n-1;i>=1;i--){
while(m>k&&cross(ch[m-2],ch[m-1],p[i])<=0)m--;
ch[m++]=p[i];
}
if(n)m--;
}
double up(point a,point b){
double ans=0;
for(int i=0;i<m;i++)
ans=max(ans,cross(a,b,ch[i])*0.5);
return ans;
}
double down(point a,point b){
double ans=0;
for(int i=0;i<m;i++)
ans=min(ans,cross(a,b,ch[i])*0.5);
return -ans;
}
double rotate(){
int j=1;
double ans=0;
for(int i=0;i<m;i++){
while(cross(ch[i],ch[i+1],ch[j])<cross(ch[i],ch[i+1],ch[j+1]))
j=(j+1)%m;
ans=max(ans,up(ch[i],ch[j])+down(ch[i],ch[j]));
}
return ans;
}
}sol;
point p[2005];
int main(){
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);
sol.andrew(p,n);
printf("%.3lf",sol.rotate());
return 0;
}