1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include<bits/stdc++.h> const double eps=1e-9; using namespace std; struct vec{ double x,y; vec(const double&x_=0,const double&y_=0){x=x_,y=y_;} vec operator+(const vec&b)const{return vec(x+b.x,y+b.y);} vec operator-(const vec&b)const{return vec(x-b.x,y-b.y);} double operator*(const vec&b)const{return x*b.x+y*b.y ;} double times (const vec&b)const{return x*b.y-y*b.x ;} void print()const{cout<<'('<<x<<','<<y<<')'<<endl;} double deg()const{return::atan2(x,y);} }; struct segment{ vec OA,OB; vec AB()const{return OB-OA;} segment(vec OA_=vec(),vec OB_=vec()){OA=OA_,OB=OB_;} bool is_cw(const vec&b)const{return AB().times(b-OA)<-eps;} vec inter(const segment&b)const{ double a_1,b_1,c_1; if(fabs( AB().x)<eps) a_1=1,b_1=0,c_1= OA.x; else{ a_1= OA.y /( OA.x- OB.x)+ OB.y /( OB.x- OA.x); c_1= OA.y* OB.x/( OA.x- OB.x)+ OB.y* OA.x/( OB.x- OA.x); b_1=-1; } double a_2,b_2,c_2; if(fabs(b.AB().x)<eps) a_2=1,b_2=0,c_2=b.OA.x; else{ a_2=b.OA.y /(b.OA.x-b.OB.x)+ b.OB.y /(b.OB.x-b.OA.x); c_2=b.OA.y*b.OB.x/(b.OA.x-b.OB.x)+ b.OB.y*b.OA.x/(b.OB.x-b.OA.x); b_2=-1; } double d=vec(a_1,b_1).times(vec(a_2,b_2)); return vec( vec(c_1,b_1).times(vec(c_2,b_2))/d, vec(a_1,c_1).times(vec(a_2,c_2))/d ); } bool operator<(const segment&b)const{ return AB().deg()<b.AB().deg(); } }; constexpr int maxn=5005; int N,M,K;vec A[maxn];double Ans=INFINITY; segment P[maxn],Seg[maxn];deque<segment>Q; vec back_point(){return(----Q.end())->inter(*--Q.end());} vec front_point(){return(++Q.begin())->inter(*Q.begin());} int read(){ int f=1,ret=0;char ch=getchar(); while(!isdigit(ch)){if(ch=='-')f=-f; ch=getchar();} while( isdigit(ch)) ret=(ret<<3)+(ret<<1)+(ch&15),ch=getchar(); return f*ret; } int main(){ N=read()+2; for(int i=2;i< N;i++) scanf("%lf%lf",&A[i].x,&A[i].y); A[1].x=A[2].x,A[1].y=A[2].y+1,A[N].x=A[N-1].x,A[N].y=A[N-1].y+1; for(int i=1;i< N;i++) P[++K]=segment(A[i],A[i+1]); sort(P+1,P+K+1); reverse(P+1,P+K+1); for(int i=1;i<=K;i++){ while(Q.size()>1&&P[i].is_cw( back_point())) Q.pop_back (); while(Q.size()>1&&P[i].is_cw(front_point())) Q.pop_front(); while(Q.size()&&fabs(P[i].AB().deg()-Q.back().AB().deg())<eps &&P[i].is_cw(Q.back().OA)) Q.pop_back(); if(Q.empty()||fabs(Q.back().AB().deg()-P[i].AB().deg())>eps) Q.push_back(P[i]); if(Q.size()>1&&Q.front().is_cw(back_point())) Q.pop_back(); } if(Q.size()>=2){ K=0;for(auto&x:Q) Seg[++K]=x; for(int i=1;i< K;i++) if(abs(Seg[i].AB().deg()-Seg[i+1].AB().deg())>eps) Ans=min(Ans,Seg[i].inter(Seg[i+1]).y); } printf("%.2lf\n",Ans); return 0; }
|