旋转卡壳 P1452 Beauty Contest

#include<bits/stdc++.h>
#define ld long double
#define ll long long
using namespace std;
const ld eps=1e-6;
const int N=5e5+7;
struct P{
    ld x,y;
    inline P() {}
    inline P(ld x,ld y):x(x),y(y) {}
    inline P &operator += (P o) { return x += o.x, y += o.y, *this; }
    inline P &operator -= (P o) { return x -= o.x, y -= o.y, *this; }
    inline P &operator *= (ld o) { return x *= o, y *= o, *this; }
    inline P &operator /= (ld o) { return x /= o, y /= o, *this; }
    inline friend P operator + (P a, P b) { return a += b; }
    inline friend P operator - (P a, P b) { return a -= b; }
    inline friend P operator * (P a, ld b) { return a *= b; }
    inline friend P operator / (P a, ld b) { return a /= b; }
    inline friend bool operator < (P a, P b) { return fabs(a.x - b.x) < eps ? a.y < b.y : a.x < b.x; }
    inline friend bool operator == (P a, P b) { return !(a < b) && !(b < a); }
    inline friend ld operator * (P a, P b) { return a.x * b.x + a.y * b.y; }
    inline friend ld operator % (P a, P b) { return a.x * b.y - a.y * b.x; }
    inline friend ld operator ^ (P a, P b) { return a * b / a.l() / b.l(); }
    inline ld a() { return atan2(y, x); }
    inline ld l() { return sqrt(*this * *this); }
    inline void r(ld o) { ld s = sin(o), c = cos(o), X = x * c - y * s, Y = x * s + y * c; x = X, y = Y; }
};
int n,m;
inline ld S(P x,P a,P b){
    return abs((a-x)%(b-x)/(a-b).l());
}
P a[N],p[N];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) scanf("%Lf%Lf",&a[i].x,&a[i].y);
    sort(a+1,a+1+n);
    n=unique(a+1,a+1+n)-a-1;
    for(int i=1;i<=n;i++){
        while(m>1&&(p[m]-p[m-1])%(a[i]-p[m-1])<=0) --m;
        p[++m]=a[i];
    }
    int o=m;
    for(int i=n-1;i;i--){
        while(m>o&&(p[m]-p[m-1])%(a[i]-p[m-1])<=0) --m;//也是必须小于等于 
        p[++m]=a[i];
    }
    if (m<3){
        cout<<0<<endl;
        return 0;
    }
    if (m==3){
        ld ans=(p[1]-p[2]).l();
        printf("%lld\n",(ll)(ans*ans+0.5));
        return 0;
    }
    int t=1;
    ld ans=0;
    for (int i = 1; i < m; i++) {
        while (S(p[t],p[i],p[i+1])<=S(p[t+1],p[i],p[i+1])) t=t%(m-1)+1;//此处一定为小于等于。。我觉得这种算法实际上是对于每个点求出了它的对踵边,所以不漏。。而一个边会有多个对踵点,所以从这个角度想会觉得有漏掉的。。 
        ans=max(ans,max((p[t]-p[i]).l(),(p[t]-p[i+1]).l())); 
    }
    cout<<(ll)(ans*ans+0.5)<<endl;
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Hikigaya/p/11913456.html