被ABC赛后加的hack卡WA了
#include <bits/stdc++.h>
#define ld long double
using namespace std;
const ld EPS=1e-10;
int dcmp(ld x){
if(fabs(x)<EPS) return 0;
if(x>0) return 1;
return -1;
}
struct Point{
ld x,y;
Point(ld x=0,ld y=0):x(x),y(y){}
};
struct Vector{
ld x,y;
Vector(ld x=0,ld y=0):x(x),y(y){}
};
Vector operator + (Vector A,Vector B){
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator - (Vector A,Vector B){
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator - (Point A,Point B){
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator * (Vector A, ld p){
return Vector(A.x*p,A.y*p);
}
Vector operator / (Vector A, ld p){
return Vector(A.x/p,A.y/p);
}
Point operator + (Point A, Vector B){
return Point(A.x+B.x,A.y+B.y);
}
Point operator - (Point A, Vector B){
return Point(A.x-B.x,A.y-B.y);
}
bool operator == (const Point& A,const Point&B){
return dcmp(A.x-B.x)==0 && dcmp(A.y-B.y)==0;
}
bool operator < (const Point& A,const Point& B){
return dcmp(A.x-B.x)==0 && A.y<B.y || A.x<B.x;
}
ld Dot(Vector A,Vector B){
return A.x*B.x+A.y*B.y;
}
ld Length(Vector A){
return sqrt(Dot(A,A));
}
ld Angle(Vector A,Vector B){
return acos(Dot(A,B)/Length(A)/Length(B));
}
ld Cross(Vector A,Vector B){
return A.x*B.y-A.y*B.x;
}
ld Area(Point A,Point B,Point C){
return Cross(B-A,C-A);
}
Vector Rotate(Vector A,ld r){
return Vector(A.x*cos(r)-A.y*sin(r),A.y*cos(r)+A.x*sin(r));
}
Vector Normal(Vector A){
return Vector(-A.y/Length(A),A.x/Length(A));
}
Point GetLineInterSection(Point A,Vector B,Point C,Vector D){
return A+B*(Cross(D,A-C)/Cross(B,D));
}
ld DistanceToLine(Point A,Point B,Point C){
return fabs(Cross(C-B,B-A)/Length(C-B));
}
ld DistanceToSepment(Point A,Point B,Point C){
if(B==C) return Length(A-B);
if(dcmp(Dot(C-B,A-B))<0)return Length(A-B);
if(dcmp(Dot(C-B,A-C))>0)return Length(A-C);
return fabs(Cross(C-B,A-B)/Length(C-B));
}
Point GetLineProjection(Point A,Point B,Point C){
return B+(C-B)*Dot(C-B,A-B)/Dot(C-B,C-B);
}
bool SegmentProperIntersection(Point A1,Point A2,Point B1,Point B2){
return dcmp(Cross(A2-A1,B1-A1))*dcmp(Cross(A2-A1,B2-A1))<0
&& dcmp(Cross(B2-B1,A1-B1))*dcmp(Cross(B2-B1,A2-B1))<0;
}
int ConvexHullAndrew(int n,Point* a,Point* b){
sort(a+1,a+1+n);
int m=0;
for(int i=1;i<=n;i++){
while(m>1&&Cross(b[m]-b[m-1],a[i]-b[m-1])<=0) m--;
b[++m]=a[i];
}
int k=m;
for(int i=n-1;i>=1;i--){
while(m>k&&Cross(b[m]-b[m-1],a[i]-b[m-1])<=0) m--;
b[++m]=a[i];
}
if(n>1) m--;
return m;
}
ld RotatingCalipers(int n,Point *a){
int j=2;
ld res=0;
for(int i=1;i<=n;i++){
while(Cross(a[i+1]-a[i],a[j]-a[i])<Cross(a[i+1]-a[i],a[j+1]-a[i])) j=j%n+1;
res = max(res,max(Length(a[i]-a[j]),Length(a[i+1]-a[j])));
}
return res;
}
ld PassPolygon(Point s,Point t,int n,Point *a,Point *b,Point *c){
bool flag = 1;
for(int i=1;i<=n;i++) {
if(SegmentProperIntersection(s, t, a[i], a[i % n + 1])) flag = 0;
}
if(flag) return Length(t - s);
int cnt = 2, m;
ld ans1 = 0,ans2 = 0;
b[1] = s;
b[2] = t;
for(int i=1;i<=n;i++)
if(Cross(t - s,a[i] - s) > 0) b[++cnt] = a[i];
m = ConvexHullAndrew(cnt, b, c);
for(int i=1;i<=m;i++) ans1 += Length(c[i] - c[i % m + 1]);
b[1] = s;
b[2] = t;
cnt = 2;
for(int i=1;i<=n;i++)
if(Cross(t - s,a[i] - s) < 0) b[++cnt] = a[i];
m = ConvexHullAndrew(cnt, b, c);
for(int i=1;i<=m;i++) ans2 += Length(c[i] - c[i % m + 1]);
return min(ans1 , ans2) - Length(t - s);
}
const int N=1e5+5;
int n;
Point a[N],s,t,b[N],c[N];
int main(){
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin >> n;
for(int i=1;i<=n;i++){
ld x,y;
cin >> x >> y;
a[i] = Point(x, y);
}
ld x,y;
cin >> x >> y;
s = Point(x, y);
cin >> x >> y;
t = Point(x, y);
cout << fixed << setprecision(8);
cout << PassPolygon(s, t, n, a, b, c);
return 0;
}