import java.util.*; public class f1 { public static Scanner in=new Scanner(System.in).useLocale(Locale.US); public static final double eps=1e-12; public static final boolean debug=false; public class Point { public long x,y; public Point(long x,long y) { this.x=x; this.y=y; } Point min(Point p) { return new Point(this.x-p.x,this.y-p.y); } long cross(Point p) { return this.x*p.y-this.y*p.x; } long mult(Point p) { return this.x*p.x+this.y*p.y; } long dist2(Point p) { Point d=this.min(p); return d.x*d.x+d.y*d.y; } double len() { return Math.sqrt(this.x*this.x+this.y*this.y); } public String toString() { return "("+x+","+y+")"; } int side(Point a,Point b) { long ret=b.min(a).cross(this.min(a)); if(ret<0) return -1; else if(ret>0) return +1; else return 0; } boolean onseg(Point a,Point b) { return this.side(a,b)==0&&this.dist2(a)<=a.dist2(b)&&this.dist2(b)<=a.dist2(b); } } public class Seg { public Point a,b; public List crosses; public Seg(Point a,Point b,List crosses) { this.a=a; this.b=b; this.crosses=crosses; } public String toString() { return a+"-"+b; } } public class Event implements Comparable { public double pos; public int type; public Event(double pos,int type) { this.pos=pos; this.type=type; } public int compareTo(Event e) { if(pose.pos) return +1; else if(type>e.type) return -1; else if(type0) return +1; else return 0; } double smindist(Point c,Point a,Point b) { return b.min(a).cross(c.min(a))/b.min(a).len(); } double mindist(Point c,Point a,Point b) { return Math.abs(smindist(c,a,b)); } boolean perpendicular(Point a,Point b,Point c,Point d) { return b.min(a).mult(d.min(c))==0; } double project(Point c,Point a,Point b) { return b.min(a).mult(c.min(a))/b.min(a).len()/b.min(a).len(); } double transfer(Point c,Point d,Point a,Point b) { double num=c.min(a).mult(d.min(c)); double den=b.min(a).mult(d.min(c)); return num/den; } boolean can(double want,List testsegs,Point[][] continents) { for(int i=0;i events=new ArrayList(); for(int j=0;jwant) continue; double center=project(c,a,b); double diff=Math.sqrt(want*want-d*d)/b.min(a).len(); events.add(new Event(center-diff,+1)); events.add(new Event(center+diff,-1)); if(debug) System.out.println("\t"+(center-diff)+".."+(center+diff)+" [point "+j+","+k+"="+c+"]"); } for(int j=0;jwant&&db>want||da<-want&&db<-want) continue; if(da>want) fa=(want-da)/(db-da); if(da<-want) fa=(-want-da)/(db-da); if(db>want) fb=(want-da)/(db-da); if(db<-want) fb=(-want-da)/(db-da); if(fa>fb) throw new RuntimeException("fa>fb"); double from=fa,to=fb; if(perpendicular(a,b,c,d)) { double pos=project(a,c,d); if(pos<0||pos>1) continue; } else { double fc=transfer(c,d,a,b),fd=transfer(d,c,a,b); from=Math.max(from,Math.min(fc,fd)); to=Math.min(to,Math.max(fc,fd)); } if(from>to) continue; events.add(new Event(from,+1)); events.add(new Event(to,-1)); if(debug) System.out.println("\t"+from+".."+to+" [seg "+j+","+k+"="+c+"-"+d+"]"); } Collections.sort(events); int cur=0; boolean need=false; for(int j=0;j testsegs=new ArrayList(); for(int i=0;i+1 crosses=new ArrayList(); Point a=waypoints[i],b=waypoints[i+1]; for(int j=0;jcheckden||checknum2<0||checknum2>checkden) continue; long realden=d.min(c).cross(b.min(a)); long realnum=d.min(c).cross(c.min(a)); crosses.add(1.0*realnum/realden); } } boolean nextoncontinent=oncontinent^(crosses.size()%2==1); if(!oncontinent) crosses.add(0.0); if(!nextoncontinent) crosses.add(1.0); Collections.sort(crosses); if(crosses.size()%2!=0) throw new RuntimeException("number of crosses not divisible by 2"); testsegs.add(new Seg(a,b,crosses)); oncontinent=nextoncontinent; } if(!oncontinent) throw new RuntimeException("Not ending on continent"); if(debug) { System.out.println(can(5,testsegs,continents)); } else { double l=0,h=1; while(!can(h,testsegs,continents)) { l=h; h*=2; } for(int i=0;i<1000;++i) { if(h-l<1e-9) break; double m=l+(h-l)/2; if(!can(m,testsegs,continents)) l=m; else h=m; } System.out.println((l+h)/2); } } public static void main(String[] args) { int n=in.nextInt(); for(int i=0;i