bzoj1069: [SCOI2007]最大土地面积

传送门

旋转卡壳。

答案一定出现在对踵点中。

//Achen
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<queue>
#include<cmath>
const int N=2007; 
#define For(i,a,b) for(int i=(a);i<=(b);i++)
#define Rep(i,a,b) for(int i=(a);i>=(b);i--)
#define eps 1e-15
typedef long long LL;
typedef double db;
using namespace std;
int n,top;
db ans;

template<typename T>void read(T &x)  {
    char ch=getchar(); x=0; T f=1;
    while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
    if(ch=='-') f=-1,ch=getchar();
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
}

struct pt {
    db x,y;
    pt(){}
    pt(db x,db y):x(x),y(y){}
}p[N],q[N];

int dcmp(db x) { return fabs(x)<=eps?0:(x>0?1:-1); }
bool operator == (const pt&A,const pt&B) { return dcmp(A.x-B.x)==0&&dcmp(A.y-B.y)==0; }
bool operator < (const pt&A,const pt&B) { return dcmp(A.x-B.x)==0?dcmp(A.y-B.y)<0:dcmp(A.x-B.x)<0; }
pt operator + (const pt&A,const pt&B) { return pt(A.x+B.x,A.y+B.y); }
pt operator - (const pt&A,const pt&B) { return pt(A.x-B.x,A.y-B.y); }
pt operator * (const pt&A,db &B) { return pt(A.x*B,A.y*B); }
pt operator / (const pt&A,db &B) { return pt(A.x/B,A.y/B); }
db cross(pt A,pt B) { return A.x*B.y-A.y*B.x; }
db dot(pt A,pt B) { return A.x*B.x+A.y*B.y; }
db length(pt A) { return dot(A,A); }

bool cmp(const pt&A,const pt&B) {
    return cross(A-p[1],B-p[1])==0?length(A-p[1])<length(B-p[1]):cross(A-p[1],B-p[1])>0;
}

void get_ham() {
    For(i,2,n) if(p[i]<p[1]) swap(p[i],p[1]); 
    sort(p+2,p+n+1,cmp);
    q[top=1]=p[1]; q[++top]=p[2];
    For(i,3,n) {
        while(top>1&&dcmp(cross(q[top]-q[top-1],p[i]-q[top-1]))<=0) top--;
        q[++top]=p[i];
    }
}

void RC() {
    q[top+1]=q[1];
    int now1=2;
    For(i,1,top) {
        while(dcmp(cross(q[i+1]-q[i],q[now1]-q[i])-cross(q[i+1]-q[i],q[now1+1]-q[i]))<0) {
            now1++; if(now1==top+1) now1=1;
        }
        int now2=i+2>top?(i+2)%top:i+2;
        for(int j=(i==top)?1:i+1;j!=now1;(j+1<=top)?j++:j=1) {
            while(dcmp(cross(q[j+1]-q[j],q[now2]-q[j])-cross(q[j+1]-q[j],q[now2+1]-q[j]))<0) {
                now2++; if(now2==top+1) now2=1;
            }
            ans=max(ans,cross(q[j]-q[i],q[now1]-q[i])+cross(q[now1]-q[i],q[now2]-q[i]));
        }
    }
}

int main() {
#ifdef DEBUG
    freopen(".in","r",stdin);
    freopen(".out","w",stdout);
#endif
    read(n);
    For(i,1,n) { scanf("%lf%lf",&p[i].x,&p[i].y); }
    get_ham(); RC();
    printf("%.3lf\n",ans/2.0);
    return 0;
}
/*
5
0 0
1 0
1 1
0 1
0.5 0.5
*/
View Code

 

posted @ 2018-03-19 20:07  啊宸  阅读(169)  评论(0编辑  收藏  举报