BZOJ题面

# 思路

## 凸包

graham算法的复杂度是$O(n\log n)$，瓶颈是排序

# Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<cmath>
#define eps 1e-9
#define ll long long
using namespace std;
int re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
struct node{
double x,y;
node(double xx=0.0,double yy=0.0){x=xx;y=yy;}
inline bool operator <(const node &b){return ((fabs(y-b.y)<eps)?(x<b.x):(y<b.y));}
inline friend bool operator ==(const node &a,const node &b){return ((fabs(a.x-b.x)<eps)&&(fabs(a.y-b.y)<eps));}
inline friend bool operator !=(const node &a,const node &b){return !(a==b);}
inline friend node operator +(const node &l,const node &r){return node(l.x+r.x,l.y+r.y);}
inline friend node operator -(const node &l,const node &r){return node(l.x-r.x,l.y-r.y);}
inline friend node operator *(node l,double r){return node(l.x*r,l.y*r);}
inline friend double operator *(const node &l,const node &r){return l.x*r.y-l.y*r.x;}
inline friend double operator /(const node &l,const node &r){return l.x*r.x+l.y*r.y;}
inline friend double dis(const node &a){return sqrt(a.x*a.x+a.y*a.y);}
}a[100010],q[100010],x[10];
int n,top;double ans=1e60;
inline bool cmp(node l,node r){
double tmp=(a[1]-l)*(a[1]-r);
if(fabs(tmp)<eps) return dis(a[1]-l)<dis(a[1]-r);
else return tmp>0;
}
void graham(){//get a counter-clockwise convex
int i;
for(i=2;i<=n;i++){
if(a[i]<a[1]) swap(a[1],a[i]);
}
sort(a+2,a+n+1,cmp);
q[++top]=a[1];
q[++top]=a[2];
for(i=3;i<=n;i++){
while(top>1&&((q[top]-q[top-1])*(a[i]-q[top])<eps)) top--;
q[++top]=a[i];
}
q[0]=q[top];
}
void RC(){//RotatingCalipers
int l=1,r=1,p=1,i;
double L,R,D,H,tmp;
for(i=0;i<top;i++){
D=dis(q[i]-q[i+1]);
while((q[i+1]-q[i])*(q[p+1]-q[i])-(q[i+1]-q[i])*(q[p]-q[i])>-eps) p=(p+1)%top;
while((q[i+1]-q[i])/(q[r+1]-q[i])-(q[i+1]-q[i])/(q[r]-q[i])>-eps) r=(r+1)%top;
if(i==0) l=r;
while((q[i+1]-q[i])/(q[l+1]-q[i])-(q[i+1]-q[i])/(q[l]-q[i])<eps) l=(l+1)%top;
L=(q[i+1]-q[i])/(q[l]-q[i])/D;
R=(q[i+1]-q[i])/(q[r]-q[i])/D;
H=(q[i+1]-q[i])*(q[p]-q[i])/D;
tmp=(R-L)*H;
if(tmp<ans){
ans=tmp;
x[0]=q[i]+(q[i+1]-q[i])*(R/D);
x[1]=x[0]+(q[r]-x[0])*(H/dis(x[0]-q[r]));
x[2]=x[1]-(x[0]-q[i])*((R-L)/dis(q[i]-x[0]));
x[3]=x[2]-(x[1]-x[0]);
}
}
}
int main(){