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);
}

这里写图片描述

posted @ 2016-12-27 11:24  SiriusRen  阅读(128)  评论(0编辑  收藏  举报