BZOJ 1069 求凸包+旋转卡壳
思路:
求凸包:
先按照x轴排个序
从左往右扫一遍 找到上凸壳 (用叉积)
再从右往左扫一遍 求下凸壳
搞个旋转卡壳就好啦~
嗯 我手懒
用的C++ Complex库
巨好用!
//By SiriusRen
#include <cstdio>
#include <complex>
#include <algorithm>
using namespace std;
#define Cplexd complex<double>
int n,q[4444];
double xx,yy;
Cplexd ff[2222];
bool cmp(Cplexd a,Cplexd b){return a.real()<b.real();}
double cj(int x,int y,int z){
Cplexd tmp=ff[z]-ff[y];tmp.imag()=-tmp.imag();
return (tmp*(ff[x]-ff[y])).imag();
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%lf%lf",&xx,&yy);
ff[i].real()=xx,ff[i].imag()=yy;
}
sort(ff+1,ff+1+n,cmp);
q[1]=1,q[2]=2;int ta=2;
for(int i=3;i<=n;q[++ta]=i,i++)
while(ta>=2&&cj(q[ta],q[ta-1],i)>=0)ta--;
int ta2=ta;
for(int i=n-1;i;q[++ta]=i,i--)
while(ta>=ta2+1&&cj(q[ta],q[ta-1],i)>=0)ta--;
double ans=0.0;
for(int i=1,l=2,r=4;i<ta;l=i+1,r=i+3,i++)
for(int j=i+2;j<ta-1;j++){
while(l<j-1&&cj(q[j],q[i],q[l])<=cj(q[j],q[i],q[l+1]))l++;
while(r<=j||(r<ta-1&&cj(q[r],q[i],q[j])<=cj(q[r+1],q[i],q[j])))r++;
ans=max(ans,cj(q[j],q[i],q[l])+cj(q[r],q[i],q[j]));
}
printf("%.3f",ans/2);
}