Problem:
問題文
$N$ 本の線分 $s_1, s_2, ..., s_N$ が与えられる。このとき、
dist$(s_i, s_j)$, ( $1 \leq i,j \leq N, i \ne j $ )
のとりうる最小値を求めよ。
dist$(s_i, s_j)$ は
$\sqrt{(x_i-x_j)^2 + (y_i-y_j)^2}$, ( $(x_i,y_i)$ は $s_i$ 上の点、$(x_j,y_j)$ は $s_j$ 上の点)
のとりうる最小値で定義される。
以下はSample Inputのデータセットを図示したものである。
入力
入力は以下の形式に従う。与えられる数は全て整数である。
$N$
$x_{1,1}$ $y_{1,1}$ $x_{1,2}$ $y_{1,2}$
$x_{2,1}$ $y_{2,1}$ $x_{2,2}$ $y_{2,2}$
$...$
$x_{N,1}$ $y_{N,1}$ $x_{N,2}$ $y_{N,2}$
$s_i$は$(x_{i,1}, y_{i,1})$，$(x_{i,2}, y_{i,2})$を端点とする線分である。
制約
$2 \leq N \leq 10^5$
$0 \leq x_{i,j}, y_{i,j} \leq 100$
$(x_{i,1}, y_{i,1}) \neq (x_{i,2}, y_{i,2})$
出力
最小値を1行に出力せよ。出力される値には$10^{-5}$より大きな誤差があってはならない。
Sample Input 1
4
2 0 2 25
0 30 15 20
16 20 5 15
23 0 23 30
Output for the Sample Input 1
0.41380294
Sample Input 2
6
0 0 0 5
1 3 3 5
6 0 6 10
7 4 10 4
11 1 11 3
7 0 10 0
Output for the Sample Input 2
1.00000000
Sample Input 3
6
5 5 5 45
7 45 19 45
7 30 19 30
21 34 21 44
26 45 36 28
45 45 26 5
Output for the Sample Input 3
0.83553169
Sample Input 4
11
10 10 10 90
10 90 35 90
10 60 35 60
35 60 35 90
40 10 40 90
37 45 60 45
60 10 60 45
65 10 65 90
65 90 90 90
65 60 90 65
90 60 90 90
Output for the Sample Input 4
0.00000000

Submitted solutions:

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;

const double EPS = 1e-10;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};
double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}

bool intersectSP(const L& s, const P &p){
    return abs(cross(s[0]-p, s[1]-p))<EPS  && dot(s[0]-p, s[1]-p)<EPS;
}
bool intersectSS(const L& a, const L& b){
    return ( ccw(a[0],a[1],b[0]) *ccw(a[0],a[1],b[1]) <= 0 ) &&
        ( ccw(b[0],b[1],a[0]) *ccw(b[0],b[1],a[1]) <= 0 );
}
double distanceLP(const L &l, const P &p) {
  return abs(cross(l[1]-l[0], p-l[0])) /abs(l[1]-l[0]);
}
double distanceSP(const L &s, const P &p) {
  if(dot(s[1]-s[0], p-s[0]) < EPS) return abs(p-s[0]);
  if(dot(s[0]-s[1], p-s[1]) < EPS) return abs(p-s[1]);
  return distanceLP(s, p);
}
double distanceSS(const L &s, const L &t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
             min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}

const int limit = 101*101/2;

int main(){
	int n;
	cin >> n;
	vector<L> line(n);
	for(int i=0; i<n; i++){
		int x1,y1,x2,y2;
		cin >> x1 >> y1 >> x2 >> y2;
		line[i] = L(P(x1,y1), P(x2,y2));
	}
	if(n > limit){
		cout << 0 << endl;
		return 0;
	}
	
	double ans = INF;
	for(int i=0; i<n; i++){
		for(int j=i+1; j<n; j++){
			ans = min(ans, distanceSS(line[i], line[j]));
		}
	}
	cout << fixed;
	cout << setprecision(6);
	cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 900
memory_kb: 5640
final_rank: 13

code_snippet: #include<bits/stdc++.h>

using namespace std;

const double EPS = 1e-8, PI = acos(-1);

inline bool eq(double a, double b) { return fabs(b - a) < EPS; }

struct Point
{
  double x, y;

  Point() {}

  Point(double x, double y) : x(x), y(y) {}

  Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }

  Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }

  Point operator*(const double b) const { return Point(x * b, y * b); }

  Point operator*(const Point &b) const { return Point(x * b.x - y * b.y, x * b.y + y * b.x); }

  Point operator/(const double b) const { return Point(x / b, y / b); }

  bool operator<(const Point &b) const { return x != b.x ? x < b.x : y < b.y; }

  bool operator==(const Point &b) const { return eq(x, b.x) && eq(y, b.y); }

  double norm() { return x * x + y * y; }

  double arg() { return atan2(x, y); }

  double abs() { return sqrt(norm()); }

  Point rotate(double theta) { return Point(cos(theta) * x - sin(theta) * y, sin(theta) * x + cos(theta) * y); }

  Point rotate90() { return Point(-y, x); }

  friend ostream &operator<<(ostream &os, Point &p) { return os << "(" << p.x << "," << p.y << ")"; }

  friend istream &operator>>(istream &is, Point &a) { return is >> a.x >> a.y; }
};

double cross(const Point &a, const Point &b)
{
  return a.x * b.y - a.y * b.x;
}

double dot(const Point &a, const Point &b)
{
  return a.x * b.x + a.y * b.y;
}

struct Segment
{
  Point a, b;

  Segment() {};

  Segment(Point a, Point b) : a(a), b(b) {};

  friend ostream &operator<<(ostream &os, Segment &p) { return os << "(" << p.a.x << "," << p.a.y << ") to (" << p.b.x << "," << p.b.y << ")"; }

  friend istream &operator>>(istream &is, Segment &a) { return is >> a.a.x >> a.a.y >> a.b.x >> a.b.y; }
};

int ccw(const Point &a, Point b, Point c)
{
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < 0) return +2;
  if(b.norm() < c.norm()) return -2;
  return 0;
}

Point Projection(const Segment &l, const Point &p)
{
  double t = dot(p - l.a, l.a - l.b) / (l.a - l.b).norm();
  return l.a + (l.a - l.b) * t;
}

bool Intersect(const Segment &s, const Point &p)
{
  return ccw(s.a, s.b, p) == 0;
}

bool Intersect(const Segment &s, const Segment &t)
{
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

double Distance(const Segment &s, const Point &p)
{
  Point r = Projection(s, p);
  if(Intersect(s, r)) return (r - p).abs();
  return min((s.a - p).abs(), (s.b - p).abs());
}

double Distance(const Segment &a, const Segment &b)
{
  if(Intersect(a, b)) return 0;
  return min(min(Distance(a, b.a), Distance(a, b.b)), min(Distance(b, a.a), Distance(b, a.b)));
}

int main()
{
  int N;
  cin >> N;

  if(N > 5100) {
    cout << 0 << endl;
    return (0);
  }

  vector< Segment > seg(N);
  double ret = 1e9;
  for(int i = 0; i < N; i++) {
    cin >> seg[i].a >> seg[i].b;
    for(int j = 0; j < i; j++) {
      ret = min(ret, Distance(seg[i], seg[j]));
    }
  }
  cout << fixed << setprecision(10) << ret << endl;
}
accuracy: 1
time_ms: 650
memory_kb: 3248
final_rank: 10

code_snippet: #include<bits/stdc++.h>

using namespace std;

const double EPS = 1e-8, PI = acos(-1);

inline bool eq(double a, double b) { return fabs(b - a) < EPS; }

struct Point
{
  double x, y;

  Point() {}

  Point(double x, double y) : x(x), y(y) {}

  Point operator+(const Point &b) const { return Point(x + b.x, y + b.y); }

  Point operator-(const Point &b) const { return Point(x - b.x, y - b.y); }

  Point operator*(const double b) const { return Point(x * b, y * b); }

  Point operator*(const Point &b) const { return Point(x * b.x - y * b.y, x * b.y + y * b.x); }

  Point operator/(const double b) const { return Point(x / b, y / b); }

  bool operator<(const Point &b) const { return x != b.x ? x < b.x : y < b.y; }

  bool operator==(const Point &b) const { return eq(x, b.x) && eq(y, b.y); }

  double norm() { return x * x + y * y; }

  double arg() { return atan2(x, y); }

  double abs() { return sqrt(norm()); }

  Point rotate(double theta) { return Point(cos(theta) * x - sin(theta) * y, sin(theta) * x + cos(theta) * y); }

  Point rotate90() { return Point(-y, x); }

  friend ostream &operator<<(ostream &os, Point &p) { return os << "(" << p.x << "," << p.y << ")"; }

  friend istream &operator>>(istream &is, Point &a) { return is >> a.x >> a.y; }
};

double cross(const Point &a, const Point &b)
{
  return a.x * b.y - a.y * b.x;
}

double dot(const Point &a, const Point &b)
{
  return a.x * b.x + a.y * b.y;
}

double RadianToDegree(double r)
{
  return (r * 180.0 / acos(-1));
}

double DegreeToRadian(double d)
{
  return (d * acos(-1) / 180.0);
}

double GetAngle(const Point &a, const Point &b, const Point &c)
{
  const Point v = b - a, w = c - b;
  double alpha = atan2(v.y, v.x), beta = atan2(w.y, w.x);
  if(alpha > beta) swap(alpha, beta);
  double theta = (beta - alpha);
  return min(theta, 2 * acos(-1) - theta);
}

struct Line
{
  Point a, b;

  Line() {};

  Line(Point a, Point b) : a(a), b(b) {};

  // Ax + By = C
  Line(double A, double B, double C)
  {
    if(eq(A, 0)) {
      a = Point(0, C / B);
      b = Point(1, C / B);
    } else if(eq(B, 0)) {
      a = Point(C / A, 0);
      b = Point(C / A, 1);
    } else {
      a = Point(0, C / B);
      b = Point(C / A, 0);
    }
  }

  friend ostream &operator<<(ostream &os, Line &p) { return os << "(" << p.a.x << "," << p.a.y << ") to (" << p.b.x << "," << p.b.y << ")"; }

  friend istream &operator>>(istream &is, Line &a) { return is >> a.a.x >> a.a.y >> a.b.x >> a.b.y; }
};

struct Segment
{
  Point a, b;

  Segment() {};

  Segment(Point a, Point b) : a(a), b(b) {};

  friend ostream &operator<<(ostream &os, Segment &p) { return os << "(" << p.a.x << "," << p.a.y << ") to (" << p.b.x << "," << p.b.y << ")"; }

  friend istream &operator>>(istream &is, Segment &a) { return is >> a.a.x >> a.a.y >> a.b.x >> a.b.y; }
};

struct Circle
{
  Point p;
  double r;

  Circle() {};

  Circle(Point p, double r) : p(p), r(r) {};
};

typedef vector< Point > Polygon;
typedef vector< Segment > Segments;
typedef vector< Line > Lines;
typedef vector< Circle > Circles;
typedef pair< Point, Point > PointPoint;

int ccw(const Point &a, Point b, Point c)
{
  b = b - a, c = c - a;
  if(cross(b, c) > EPS) return +1;
  if(cross(b, c) < -EPS) return -1;
  if(dot(b, c) < 0) return +2;
  if(b.norm() < c.norm()) return -2;
  return 0;
}

Point Projection(const Segment &l, const Point &p)
{
  double t = dot(p - l.a, l.a - l.b) / (l.a - l.b).norm();
  return l.a + (l.a - l.b) * t;
}

bool Intersect(const Segment &s, const Point &p)
{
  return ccw(s.a, s.b, p) == 0;
}

bool Intersect(const Segment &s, const Segment &t)
{
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

double Distance(const Segment &s, const Point &p)
{
  Point r = Projection(s, p);
  if(Intersect(s, r)) return (r - p).abs();
  return min((s.a - p).abs(), (s.b - p).abs());
}

double Distance(const Segment &a, const Segment &b)
{
  if(Intersect(a, b)) return 0;
  return min(min(Distance(a, b.a), Distance(a, b.b)), min(Distance(b, a.a), Distance(b, a.b)));
}

int main()
{
  int N;
  cin >> N;

  if(N > 5100) {
    cout << 0 << endl;
    return (0);
  }

  vector< Segment > seg(N);
  double ret = 1e9;
  for(int i = 0; i < N; i++) {
    cin >> seg[i].a >> seg[i].b;
    for(int j = 0; j < i; j++) {
      ret = min(ret, Distance(seg[i], seg[j]));
    }
  }
  cout << fixed << setprecision(10) << ret << endl;
}
accuracy: 1
time_ms: 620
memory_kb: 3248
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
using Int = long long;
const double EPS = 1e-10;
struct Point{
  double x,y;
  Point(){}
  Point(double x,double y):x(x),y(y){}
  Point operator+(Point a){return Point(x+a.x,y+a.y);}
  Point operator-(Point a){return Point(x-a.x,y-a.y);}
};
typedef Point Vector;

struct Segment{
  Point p1,p2;
  Segment(){}
  Segment(Point p1,Point p2):p1(p1),p2(p2){}
};
typedef Segment Line;

double dot(Vector a,Vector b){
  return a.x*b.x+a.y*b.y;
}

double cross(Vector a,Vector b){
  return a.x*b.y-a.y*b.x;
}

double norm(Vector a){
  return dot(a,a);
}

double abs(Vector a){
  return sqrt(norm(a));
}

/*
1
-1
2
-2
0
 */
Int ccw(Point p0,Point p1,Point p2){
  Vector a=p1-p0;
  Vector b=p2-p0;
  if(cross(a,b) > EPS) return 1;
  if(cross(a,b) < -EPS) return -1;
  if(dot(a,b) < -EPS) return 2;
  if(norm(a)<norm(b)) return -2;
  return 0;
}

bool intersectSS(Point p1,Point p2,Point p3,Point p4){
  return (ccw(p1,p2,p3)*ccw(p1,p2,p4) <= 0 && ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0);
}

bool intersectSS(Segment s1,Segment s2){
  return intersectSS(s1.p1,s1.p2,s2.p1,s2.p2);
}

double getDistanceLP(Line l,Point p){
  return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
  if(dot(s.p2-s.p1,p-s.p1) < 0.0) return abs(p-s.p1);
  if(dot(s.p1-s.p2,p-s.p2) < 0.0) return abs(p-s.p2);
  return getDistanceLP(s,p);
}
double getDistanceSS(Segment s1,Segment s2){
  if(intersectSS(s1,s2)) return 0.0;
  return min({getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2),
	getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)});
}

Int cnt[111][111];
signed main(){  
  cin.tie(0);
  ios::sync_with_stdio(0);
  Int n;
  cin>>n;
  vector<Segment> vs(n);
  memset(cnt,0,sizeof(cnt));
  for(Int i=0;i<n;i++){
    Int x1,y1,x2,y2;
    cin>>x1>>y1>>x2>>y2;
    cnt[x1][y1]++;
    cnt[x2][y2]++;
    vs[i]=Segment(Point(x1,y1),Point(x2,y2));
  }
  cout<<fixed<<setprecision(12);
  for(Int i=0;i<111;i++){
    for(Int j=0;j<111;j++){
      if(cnt[i][j]>1){
	cout<<0.0<<endl;
	return 0;
      }
    }
  }
  assert(n<5555);
  double ans=getDistanceSS(vs[0],vs[1]);
  for(Int i=0;i<n;i++)
    for(Int j=i+1;j<n;j++)
      ans=min(ans,getDistanceSS(vs[i],vs[j]));
  cout<<ans<<endl;
  return 0;
}
accuracy: 1
time_ms: 420
memory_kb: 5628
final_rank: 7

code_snippet: #include <bits/stdc++.h>

using namespace std;

//#define double long double

const double EPS = 1e-6;
#define eq(a, b) (fabs((a)-(b)) < EPS)

struct Point {
  double x, y;
  Point(double x=0, double y=0):x(x), y(y){}
  Point operator+(Point p) {return Point(x+p.x, y+p.y);}
  Point operator-(Point p) {return Point(x-p.x, y-p.y);}
  Point operator*(double k) {return Point(x*k, y*k);}
  Point operator/(double k) {return Point(x/k, y/k);}  
};
using Vector = Point;

double dot(Vector a, Vector b) {
  return a.x*b.x+a.y*b.y;
}
double cross(Vector a, Vector b) {
  return a.x*b.y-a.y*b.x;
}
double norm(Vector a) {
  return dot(a, a);
}
double abs(Vector a) {
  return sqrt(norm(a));
}

struct Segment {
  Point p1, p2;
  Segment(Point p1=Point(), Point p2=Point()):p1(p1), p2(p2){}
};
using Line = Segment;

const int CCW = 1;
const int CW = -1;
const int BACK = 2;
const int FRONT =-2;
const int ON = 0;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a, b) > EPS) return CCW;
  if(cross(a, b) < -EPS) return CW;
  if(dot(a, b) < -EPS) return BACK;
  if(norm(a) < norm(b)) return FRONT;
  return ON;
}

bool isIntersectSS(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3)*ccw(p1, p2, p4) <= 0 &&
	  ccw(p3, p4, p1)*ccw(p3, p4, p2) <= 0);
}

bool isIntersectSS(Segment s1, Segment s2) {
  return isIntersectSS(s1.p1, s1.p2, s2.p1, s2.p2);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2-l.p1, p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s, Point p) {
  if(dot(s.p2-s.p1, p-s.p1) < 0.0) return abs(p-s.p1);
  if(dot(s.p1-s.p2, p-s.p2) < 0.0) return abs(p-s.p2);
  return getDistanceLP(s, p);
}

double getDistanceSS(Segment s1, Segment s2) {
  if(isIntersectSS(s1, s2)) return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
	     min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

int main() {
  int N;
  cin >> N;
  vector<Segment> segs(N);
  for(int i = 0; i < N; ++i) {
    Point s, t;
    cin >> s.x >> s.y >> t.x >> t.y;
    segs[i] = Segment(s, t);
  }
  if(N > 10000) {
    printf("%.12f\n", 0.0);
    return 0;
  }

  double ans = LDBL_MAX/2;
  for(int i = 0; i < N; ++i) {
    for(int j = i+1; j < N; ++j) {
      //if(i == j) continue;
      ans = min(ans, getDistanceSS(segs[i], segs[j]));
    }
  }
  //printf("%.12Lf\n", ans);
  printf("%.12f\n", ans);  
  
  return 0;
}
accuracy: 1
time_ms: 340
memory_kb: 5684
final_rank: 5

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define double long double

const double EPS = 1e-10;
#define eq(a, b) (fabs((a)-(b)) < EPS)

struct Point {
  double x, y;
  Point(double x=0, double y=0):x(x), y(y){}
  Point operator+(Point p) {return Point(x+p.x, y+p.y);}
  Point operator-(Point p) {return Point(x-p.x, y-p.y);}
  Point operator*(double k) {return Point(x*k, y*k);}
  Point operator/(double k) {return Point(x/k, y/k);}  
};
using Vector = Point;

double dot(Vector a, Vector b) {
  return a.x*b.x+a.y*b.y;
}
double cross(Vector a, Vector b) {
  return a.x*b.y-a.y*b.x;
}
double norm(Vector a) {
  return dot(a, a);
}
double abs(Vector a) {
  return sqrt(norm(a));
}

struct Segment {
  Point p1, p2;
  Segment(Point p1=Point(), Point p2=Point()):p1(p1), p2(p2){}
};
using Line = Segment;

const int CCW = 1;
const int CW = -1;
const int BACK = 2;
const int FRONT =-2;
const int ON = 0;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a, b) > EPS) return CCW;
  if(cross(a, b) < -EPS) return CW;
  if(dot(a, b) < -EPS) return BACK;
  if(norm(a) < norm(b)) return FRONT;
  return ON;
}

bool isIntersectSS(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3)*ccw(p1, p2, p4) <= 0 &&
	  ccw(p3, p4, p1)*ccw(p3, p4, p2) <= 0);
}

bool isIntersectSS(Segment s1, Segment s2) {
  return isIntersectSS(s1.p1, s1.p2, s2.p1, s2.p2);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2-l.p1, p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s, Point p) {
  if(dot(s.p2-s.p1, p-s.p1) < 0.0) return abs(p-s.p1);
  if(dot(s.p1-s.p2, p-s.p2) < 0.0) return abs(p-s.p2);
  return getDistanceLP(s, p);
}

double getDistanceSS(Segment s1, Segment s2) {
  if(isIntersectSS(s1, s2)) return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
	     min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

int main() {
  int N;
  cin >> N;
  vector<Segment> segs(N);
  for(int i = 0; i < N; ++i) {
    Point s, t;
    cin >> s.x >> s.y >> t.x >> t.y;
    segs[i] = Segment(s, t);
  }
  if(N > 5000) {
    printf("%.12f\n", 0.0);
    return 0;
  }
  double ans = 1e9;
  for(int i = 0; i < N; ++i) {
    for(int j = 0; j < N; ++j) {
      if(i == j) continue;
      ans = min(ans, getDistanceSS(segs[i], segs[j]));
    }
  }
  printf("%.12Lf\n", ans);
  
  return 0;
}
accuracy: 0.967741935483871
time_ms: 90
memory_kb: 8444
final_rank: 19

code_snippet: #include <bits/stdc++.h>

using namespace std;

const double EPS = 1e-10;
#define eq(a, b) (fabs((a)-(b)) < EPS)

struct Point {
  double x, y;
  Point(double x=0, double y=0):x(x), y(y){}
  Point operator+(Point p) {return Point(x+p.x, y+p.y);}
  Point operator-(Point p) {return Point(x-p.x, y-p.y);}
  Point operator*(double k) {return Point(x*k, y*k);}
  Point operator/(double k) {return Point(x/k, y/k);}  
};
using Vector = Point;

double dot(Vector a, Vector b) {
  return a.x*b.x+a.y*b.y;
}
double cross(Vector a, Vector b) {
  return a.x*b.y-a.y*b.x;
}
double norm(Vector a) {
  return dot(a, a);
}
double abs(Vector a) {
  return sqrt(norm(a));
}

struct Segment {
  Point p1, p2;
  Segment(Point p1=Point(), Point p2=Point()):p1(p1), p2(p2){}
};
using Line = Segment;

const int CCW = 1;
const int CW = -1;
const int BACK = 2;
const int FRONT =-2;
const int ON = 0;

int ccw(Point p0, Point p1, Point p2) {
  Vector a = p1-p0;
  Vector b = p2-p0;
  if(cross(a, b) > EPS) return CCW;
  if(cross(a, b) < -EPS) return CW;
  if(dot(a, b) < -EPS) return BACK;
  if(norm(a) < norm(b)) return FRONT;
  return ON;
}

bool isIntersectSS(Point p1, Point p2, Point p3, Point p4) {
  return (ccw(p1, p2, p3)*ccw(p1, p2, p4) <= 0 &&
	  ccw(p3, p4, p1)*ccw(p3, p4, p2) <= 0);
}

bool isIntersectSS(Segment s1, Segment s2) {
  return isIntersectSS(s1.p1, s1.p2, s2.p1, s2.p2);
}

double getDistanceLP(Line l, Point p) {
  return abs(cross(l.p2-l.p1, p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s, Point p) {
  if(dot(s.p2-s.p1, p-s.p1) < 0.0) return abs(p-s.p1);
  if(dot(s.p1-s.p2, p-s.p2) < 0.0) return abs(p-s.p2);
  return getDistanceLP(s, p);
}

double getDistanceSS(Segment s1, Segment s2) {
  if(isIntersectSS(s1, s2)) return 0;
  return min(min(getDistanceSP(s1, s2.p1), getDistanceSP(s1, s2.p2)),
	     min(getDistanceSP(s2, s1.p1), getDistanceSP(s2, s1.p2)));
}

int main() {
  int N;
  cin >> N;
  vector<Segment> segs(N);
  for(int i = 0; i < N; ++i) {
    Point s, t;
    cin >> s.x >> s.y >> t.x >> t.y;
    segs[i] = Segment(s, t);
  }
  if(N > 5000) {
    printf("%.12f\n", 0.0);
    return 0;
  }
  double ans = 1e9;
  for(int i = 0; i < N; ++i) {
    for(int j = 0; j < N; ++j) {
      if(i == j) continue;
      ans = min(ans, getDistanceSS(segs[i], segs[j]));
    }
  }
  printf("%.12f\n", ans);
  
  return 0;
}
accuracy: 0.967741935483871
time_ms: 80
memory_kb: 5664
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#define r(i,n) for(int i=0;i<n;i++)
using namespace std;
typedef double D;     
typedef complex<D> P;  
typedef pair<P, P> L; 
typedef vector<P> VP;
const D EPS = 1e-9;  
#define X real()
#define Y imag()
D dot(P a, P b) {return (conj(a)*b).X; }
D cross(P a, P b) {  return (conj(a)*b).Y;}
int ccw(P a, P b, P c) {
  b -= a;  c -= a;
  if (cross(b,c) >  EPS) return +1; 
  if (cross(b,c) < -EPS) return -1; 
  if (dot(b,c)   < -EPS) return +2; 
  if (norm(b) < norm(c)) return -2; 
  return 0;                      
}
bool isecSS(P &a1, P &a2, P &b1, P &b2) {
  return ccw(a1, a2, b1)*ccw(a1, a2, b2) <= 0 &&
         ccw(b1, b2, a1)*ccw(b1, b2, a2) <= 0;
}
bool isecSP(P &a1, P &a2, P &b) {
  return !ccw(a1, a2, b);
  //return abs(a1 - b) + abs(a2 - b) - abs(a2 - a1) < EPS;  //Perfective
}
P proj(P &a1, P &a2, P &p) {
  return a1 + dot(a2-a1, p-a1)/norm(a2-a1) * (a2-a1);
}
D distSP(P &a1, P &a2, P &p) {
  P r = proj(a1, a2, p);
  if (isecSP(a1, a2, r)) return abs(r-p);
  return min(abs(a1-p), abs(a2-p));
}
 
D distSS(P &a1, P &a2, P &b1, P &b2) {
  if (isecSS(a1, a2, b1, b2)) return 0;
  return min(min(distSP(a1, a2, b1), distSP(a1, a2, b2)),
             min(distSP(b1, b2, a1), distSP(b1, b2, a2)));
}
std::chrono::system_clock::time_point start;
std::chrono::system_clock::time_point owari;
D ans=1e19,x[10000],y[10000],xx[10000],yy[10000];
vector<P>v1,v2;
int main(){
  start = std::chrono::system_clock::now();
  int n;
  cin>>n;
  if(n>=5200){
    cout<<0<<endl;
    return 0;
  }
  r(i,n){
    cin>>x[i]>>y[i]>>xx[i]>>yy[i];
    v1.push_back(P(x[i],y[i]));
    v2.push_back(P(xx[i],yy[i]));
  }
  for(int i=0;i<n;i++){
    for(int j=i+1;j<n;j++){
      ans=min(ans,distSS(v1[i],v2[i],v1[j],v2[j]));
    }
    if(i%10==0){
      owari = std::chrono::system_clock::now();
      double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(owari-start).count();
      if(elapsed>970)break;
    }
  }
  printf("%.9f\n",ans);
}
accuracy: 1
time_ms: 970
memory_kb: 3524
final_rank: 12

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#include<random>
#pragma warning(disable:4996)
using namespace std;
using ld=double;
ld eps=1e-7;
/* ??????????????¬ */

#include <complex>

typedef complex<ld> Point;


const ld pi = acos(-1.0);
const ld dtop = pi / 180.;
const ld ptod = 1. / dtop;

namespace std {
	bool operator<(const Point &lhs, const Point &rhs) {
		if (lhs.real() < rhs.real() - eps) return true;
		if (lhs.real() > rhs.real() + eps) return false;
		return lhs.imag() < rhs.imag();
	}
}

// ????????\???
Point input_Point() {
	ld x, y;
	cin >> x >> y;
	return Point(x, y);
}

// ????????????????????????
bool eq(const ld a, const ld b) {
	return (abs(a - b) < eps);
}

// ??????
ld dot(const Point& a, const Point& b) {
	return real(conj(a) * b);
}

// ??????
ld cross(const Point& a, const Point& b) {
	return imag(conj(a) * b);
}

// ??´????????????
class Line {
public:
	Point a, b;
	Line() : a(Point(0, 0)), b(Point(0, 0)) {}
	Line(Point a, Point b) : a(a), b(b) {}
	Point operator[](const int _num)const {
		if (_num == 0)return a;
		else if (_num == 1)return b;
		else {
			assert(false);
			return Point();
		}
	}
};

// ????????????
class Circle {
public:
	Point p;
	ld r;
	Circle() : p(Point(0, 0)), r(0) {}
	Circle(Point p, ld r) : p(p), r(r) {}
};

// ccw
// 1: a,b,c??????????¨???¨?????????????????¶
//-1: a,b,c???????¨???¨?????????????????¶
// 2: c,a,b???????????´???????????¶
//-2: a,b,c???????????´???????????¶
// 0: a,c,b???????????´???????????¶
int ccw(const Point& a, const Point &b, const Point &c) {
	const Point nb(b - a);
	const Point nc(c - a);
	if (cross(nb, nc) > eps) return 1;   // a,b,c??????????¨???¨?????????????????¶
	if (cross(nb, nc) < -eps) return -1; // a,b,c???????¨???¨?????????????????¶
	if (dot(nb, nc) < 0) return 2;       // c,a,b???????????´???????????¶
	if (norm(nb) < norm(nc)) return -2;  // a,b,c???????????´???????????¶
	return 0;                          // a,c,b???????????´???????????¶
}


/* ???????????? */

// ??´?????¨??´??????????????????
bool isis_ll(const Line& l, const Line& m) {
	return !eq(cross(l.b - l.a, m.b - m.a), 0);
}

// ??´?????¨?????????????????????
bool isis_ls(const Line& l, const Line& s) {
	return isis_ll(l, s) &&
		(cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < eps);
}

// ????????¨?????????????????????
bool isis_ss(const Line& s, const Line& t) {
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// ????????´????????????
bool isis_lp(const Line& l, const Point& p) {
	return (abs(cross(l.b - p, l.a - p)) < eps);
}

// ?????????????????????
bool isis_sp(const Line& s, const Point& p) {
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a) < eps);
}

// ??????????¶?
Point proj(const Line &l, const Point& p) {
	ld t = dot(p - l.a, l.b - l.a) / norm(l.a - l.b);
	return l.a + t * (l.b - l.a);
}

//???????±??????????????????????
Point reflect(const Line &l, const Point &p) {
	Point pr = proj(l, p);
	return pr * 2.0 - p;
}

// ??´?????¨??´????????????
Point is_ll(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	assert(cross(sv, tv) != 0);
	return s.a + sv * cross(tv, t.a - s.a) / cross(tv, sv);
}
// ??´?????¨??´????????????
vector<Point> is_ll2(const Line &s, const Line& t) {
	Point sv = s.b - s.a, tv = t.b - t.a;
	if (cross(sv, tv) != 0)return vector<Point>(1, is_ll(s, t));
	else {
		vector<Point>ans;
		for (int k = 0; k < 2; ++k) {
			if (isis_sp(s, t[k]) && find(ans.begin(), ans.end(), t[k]) == ans.end())ans.push_back(t[k]);
			if (isis_sp(t, s[k]) && find(ans.begin(), ans.end(), s[k]) == ans.end())ans.push_back(s[k]);
		}
		return ans;
	}
}
// ????????¨???????????????
//???????????£????????¨???????????¨assert(false)
Point is_ss(const Line &s, const Line& t) {
	if (isis_ss(s, t)) {
		for (int k = 0; k < 2; ++k) {
			for (int l = 0; l < 2; ++l) {
				if (s[k] == t[l])return s[k];
			}
		}
		return is_ll(s, t);
	}
	else {
		//??????isis_ss?????????
		assert(false);
		return Point(0, 0);
	}
}
// ????????¨???????????????
vector<Point> is_ss2(const Line &s, const Line& t) {
	vector<Point> kouho(is_ll2(s, t));
	vector<Point>ans;
	for (auto p : kouho) {
		if (isis_sp(s, p) && isis_sp(t, p))ans.emplace_back(p);
	}
	return ans;
}
// ??´?????¨???????????¢
ld dist_lp(const Line& l, const Point& p) {
	return abs(p - proj(l, p));
}

//??´?????¨??´???????????¢
ld dist_ll(const Line& l, const Line& m) {
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

// ??´?????¨??????????????¢
ld dist_ls(const Line& l, const Line& s) {
	return isis_ls(l, s) ? 0 : min(dist_lp(l, s.a), dist_lp(l, s.b));
}

// ????????¨???????????¢
ld dist_sp(const Line& s, const Point& p) {
	Point r = proj(s, p);
	return isis_sp(s, r) ? abs(r - p) : min(abs(s.a - p), abs(s.b - p));
}

// ????????¨??????????????¢
ld dist_ss(const Line& s, const Line& t) {
	return min(min( dist_sp(s, t.a), dist_sp(s, t.b)), min(dist_sp(t, s.a), dist_sp(t, s.b) ));
}

int main()
{
	ld ans=1e18;
	int N;cin>>N;
	vector<Line>ls;
	map<pair<int,int>,int>mp;
	for (int i = 0; i < N; ++i) {
		int a,b,c,d;cin>>a>>b>>c>>d;
		if (c < a) {
			swap(a,c);
			swap(b,d);
		}
		ls.push_back(Line(Point(a,b),Point(c,d)));
		mp[make_pair(a,b)]++;
		mp[make_pair(c,d)]++;
	}
	sort(ls.begin(), ls.end(), [](const Line&l, const Line&r) {
		return l.a < r.a;
	});
	bool flag=false;
	for (auto m : mp) {
		if(m.second>=2)flag=true;
	}

	if (flag) {
		ans=0;
	}
	else {
		for (int i = 0; i < N; ++i) {
			for (int j =i+1; j < N; ++j) {
				if (ls[i].b.real() + ans -eps< ls[j].a.real()) {
					break;
				}
				if (isis_ss(ls[i],ls[j]))ans=0;
				else {
					ans = min(ans, dist_ss(ls[i], ls[j]));
				}
			}
			if(ans<eps)break;
		}
	}
	cout<<setprecision(10)<<fixed<<ans<<endl;

	return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 7424
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define MOD (ll)(1e9+7)
#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

#define EPS 1e-8
#define EQ(a) (-EPS<a && a<EPS)
#define MP make_pair

bool operator<(P l,P r){
  if(l.real()!=r.real())return l.real()<r.real();
  return l.imag()<r.imag();
}

struct line{P a,b;};

bool operator<(line l,line r){
  if(l.a!=r.a)return l.a<r.a;
  return l.b<r.b;
}

double dot(P a,P b){
  return (conj(a)*b).real();
}
double cross(P a,P b){
  return (conj(a)*b).imag();
}
double po(P a){
  return a.real()*a.real() + a.imag()*a.imag();
}

// http://www.deqnotes.net/acmicpc/2d_geometry/lines
double distance(line a,P b){
  if ( dot(a.b-a.a, b-a.a) < EPS ) return po(b-a.a);
  if ( dot(a.a-a.b, b-a.b) < EPS ) return po(b-a.b);
  double t = abs( cross(a.b-a.a, b-a.a) );
  return t*t / po(a.b-a.a);
}

// http://www5d.biglobe.ne.jp/~tomoya03/shtml/algorithm/Intersection.htm
bool intersect(line a,line b){
  double x,y;
  x = cross(a.b-a.a, b.a-a.a);
  y = cross(a.b-a.a, b.b-a.a);
  if(EQ(x)&&EQ(y))return false;
  if(x*y>EPS)return false;
  x = cross(b.b-b.a, a.a-b.a);
  y = cross(b.b-b.a, a.b-b.a);
  if(EQ(x)&&EQ(y))return false;
  if(x*y>EPS)return false;
  return true;
}

int main(){
  int n;
  scanf("%d",&n);
  if(n>5100){ // (101*101-1)/2 = 10200/2 = 5100
    // law of "su of hato"
    cout << "0.0000000" << endl;
    return 0;
  }
  assert(n <= 5100);
  // O(N^2) ~ O(1e8)
  line lines[n];
  double result = 114514.0;
  REP(i,n){
    int a,b,c,d;
    scanf("%d %d %d %d",&a,&b,&c,&d);
    if(a<c) lines[i] = (line){P(a,b),P(c,d)};
    else    lines[i] = (line){P(c,d),P(a,b)};
  }
  sort(lines,lines+n);
  REP(i,n){
    line a = lines[i];
    FOR(j,i+1,n){
      line b = lines[j];
      if(a.b.real()+result < b.a.real())break;
      if(intersect(a,b)){
        cout << "0.0000000" << endl;
        return 0;
      }
      result = min(result,
        min(min(distance(a,b.a), distance(a,b.b)),
            min(distance(b,a.a), distance(b,a.b))) );
    }
  }
  cout.precision(10);
  cout << fixed << sqrt(result) << endl;
  return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 1444
final_rank: 1

code_snippet: #include <cmath>
#include <cstdio>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;

bool ne(int* a, int* b){
	for(int i=0; i<4; i++){
		if(a[i]!=b[i]) return true;
	}
	return false;
}
double dot(int* a, int* b){
	return (a[1] - a[0]) * (b[1] - b[0]) + (a[3] - a[2]) * (b[3] - b[2]);
}
double cross(int* a, int* b){
	return (a[1] - a[0]) * (b[3] - b[2]) - (a[3] - a[2]) * (b[1] - b[0]);
}
double chk(vector<int*> vs){
    double mn=LONG_MAX;
    for(int i=0; i<vs.size(); i++) for(int j=0; j<vs.size(); j++) if(ne(vs[i], vs[j])) for(int k=0; k<2; k++){
        int p1q1[4] = { vs[i][0],vs[j][0+k],vs[i][2],vs[j][2+k] };
        int p2q1[4] = { vs[i][1],vs[j][0+k],vs[i][3],vs[j][2+k] };
        int p1q2[4] = { vs[i][0],vs[j][1],vs[i][2],vs[j][3] };
        int q1p1[4] = { vs[j][0],vs[i][0],vs[j][2],vs[i][2] };
        int q1p2[4] = { vs[j][0],vs[i][1],vs[j][2],vs[i][3] };
        if(cross(vs[i], p1q1)*cross(vs[i], p1q2)<0 && cross(vs[j], q1p1)*cross(vs[j], q1p2)<0){
            return 0;
        }
		double p1p2_p1p2 = dot(vs[i],vs[i]);
        double p1q1_p1p2 = dot(p1q1, vs[i]);
        if(p1q1_p1p2 <= 0){
            mn=min(mn,dot(p1q1,p1q1));
        }else if(p1q1_p1p2 >= p1p2_p1p2){
            mn=min(mn,dot(p2q1,p2q1));
        }else{
			double p1q1_x_p1p2 = cross(vs[i], p1q1);
            mn=min(mn,p1q1_x_p1p2*p1q1_x_p1p2/p1p2_p1p2);
        }
    }
    return mn;
}
int main(){
	int N;
	scanf("%d", &N);
	vector<int*> vs(N);
	for(int i=0; i<N; i++){
		vs[i] = new int[4];
		scanf("%d %d %d %d", &vs[i][0], &vs[i][2], &vs[i][1], &vs[i][3]);
	}
	double mn=LONG_MAX;
	for(int split=5; mn==LONG_MAX && split>0; split/=2){
		vector<vector<int*>> area(split*split, vector<int*>());
		if(area.size() == 1){
			area[0] = vs;
		}else{
			for(int i=0;i<N;i++){
				int sx = min(4,split*min(vs[i][0],vs[i][1])/100);
				int ex = split*max(vs[i][0],vs[i][1])/100;
				int sy = min(4,split*min(vs[i][2],vs[i][3])/100);
				int ey = split*max(vs[i][2],vs[i][3])/100;
				for(int x=sx; x<split && x<=ex; x++){
					for(int y=sy; y<split && y<=ey; y++){
						area[x+split*y].push_back(vs[i]);
					}
				}
			}
		}
		for(int x=0; x<split; x++){
			for(int y=0; y<split; y++){
				if(area[x+split*y].size()){
					sort(area[x+split*y].begin(), area[x+split*y].end(), [](int* a,int* b){ return min(a[0]+a[2],a[1]+a[3]) > min(b[0]+b[2],b[1]+b[3]); });
					if(x>0) area[(x-1)+split*y].push_back(area[x+split*y][0]);
					if(y>0) area[x+split*(y-1)].push_back(area[x+split*y][0]);
					if(x*y>0) area[(x-1)+split*(y-1)].push_back(area[x+split*y][0]);
				}
			}
		}
		for(int i=0;i<area.size();i++){
			mn=min(mn,chk(area[i]));
		}
	}
	printf("%f\n", sqrt(mn));
}
accuracy: 1
time_ms: 60
memory_kb: 12564
final_rank: 11

code_snippet: #include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef complex<double> P;
typedef pair<int,int> pii;
#define REP(i,n) for(ll i=0;i<n;++i)
#define REPR(i,n) for(ll i=1;i<n;++i)
#define FOR(i,a,b) for(ll i=a;i<b;++i)

#define DEBUG(x) cout<<#x<<": "<<x<<endl
#define DEBUG_VEC(v) cout<<#v<<":";REP(i,v.size())cout<<" "<<v[i];cout<<endl
#define ALL(a) (a).begin(),(a).end()

#define MOD (ll)(1e9+7)
#define ADD(a,b) a=((a)+(b))%MOD
#define FIX(a) ((a)%MOD+MOD)%MOD

#define EPS 1e-8
#define EQ(a) (-EPS<a && a<EPS)
#define MP make_pair

struct line{P a,b;};

double dot(P a,P b){
  return (conj(a)*b).real();
}
double cross(P a,P b){
  return (conj(a)*b).imag();
}
double po(P a){
  return a.real()*a.real() + a.imag()*a.imag();
}

// http://www.deqnotes.net/acmicpc/2d_geometry/lines
double distance(line a,P b){
  if ( dot(a.b-a.a, b-a.a) < EPS ) return po(b-a.a);
  if ( dot(a.a-a.b, b-a.b) < EPS ) return po(b-a.b);
  double t = abs( cross(a.b-a.a, b-a.a) );
  return t*t / po(a.b-a.a);
}

// http://www5d.biglobe.ne.jp/~tomoya03/shtml/algorithm/Intersection.htm
bool intersect(line a,line b){
  double x,y;
  x = cross(a.b-a.a, b.a-a.a);
  y = cross(a.b-a.a, b.b-a.a);
  if(EQ(x)&&EQ(y))return false;
  if(x*y>EPS)return false;
  x = cross(b.b-b.a, a.a-b.a);
  y = cross(b.b-b.a, a.b-b.a);
  if(EQ(x)&&EQ(y))return false;
  if(x*y>EPS)return false;
  return true;
}

int main(){
  int n;
  scanf("%d",&n);
  if(n>5100){ // (101*101-1)/2 = 10200/2 = 5100
    // law of "su of hato"
    cout << "0.0000000" << endl;
    return 0;
  }
  assert(n <= 5100);
  // O(N^2) ~ O(1e8)
  line lines[n];
  double result = 114514.0;
  REP(i,n){
    int a,b,c,d;
    scanf("%d %d %d %d",&a,&b,&c,&d);
    lines[i] = (line){P(a,b),P(c,d)};
  }
  REP(i,n)REP(j,i){
    line a = lines[i], b = lines[j];
    if(intersect(a,b)){
      cout << "0.0000000" << endl;
      return 0;
    }
    result = min(result,
      min(min(distance(a,b.a), distance(a,b.b)),
          min(distance(b,a.a), distance(b,a.b))) );
  }
  cout.precision(10);
  cout << fixed << sqrt(result) << endl;
  return 0;
}
accuracy: 1
time_ms: 770
memory_kb: 1440
final_rank: 9

code_snippet: #include <cassert>// c
#include <iostream>// io
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>// container
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <algorithm>// other
#include <complex>
#include <numeric>
#include <functional>
#include <random>
#include <regex>
using namespace std;

typedef long long ll;

#define ALL(c) (begin(c)),(end(c))
#define REP(i,n) FOR(i,0,n)
#define REPr(i,n) FORr(i,0,n)
#define FOR(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define FORr(i,l,r) for(int i=(int)(r)-1;i>=(int)(l);--i)
#define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))
#define UNIQUE(v) v.erase(unique(ALL(v)),v.end())
//debug
#define DUMP(x)  cerr << #x << " = " << (x)
#define LINE()    cerr<< " (L" << __LINE__ << ")"

class range {
private:
    struct Iter{
        int v;
        int operator*(){return v;}
        bool operator!=(Iter& itr) {return v < itr.v;}
        void operator++() {++v;}
    };
    Iter i, n;
public:
    range(int n) : i({0}), n({n}) {}
    range(int i, int n) : i({i}), n({n}) {}
    Iter& begin() {return i;}
    Iter& end() {return n;}
};

//output
template<typename T> ostream& operator << (ostream& os, const vector<T>& as){REP(i,as.size()){if(i!=0)os<<" "; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const vector<vector<T>>& as){REP(i,as.size()){if(i!=0)os<<endl; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const set<T>& ss){for(auto a:ss){if(a!=ss.begin())os<<" "; os<<a;}return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const pair<T1,T2>& p){os<<p.first<<" "<<p.second;return os;}
template<typename K,typename V> ostream& operator << (ostream& os, const map<K,V>& m){bool isF=true;for(auto& p:m){if(!isF)os<<endl;os<<p;isF=false;}return os;}
template<typename T1> ostream& operator << (ostream& os, const tuple<T1>& t){os << get<0>(t);return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const tuple<T1,T2>& t){os << get<0>(t)<<" "<<get<1>(t);return os;}
template<typename T1,typename T2,typename T3> ostream& operator << (ostream& os, const tuple<T1,T2,T3>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6,typename T7> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t)<<" "<<get<6>(t);return os;}

//input
char tmp[1000];
#define nextInt(n) scanf("%d",&n)
#define nextLong(n) scanf("%lld",&n) //I64d
#define nextDouble(n) scanf("%lf",&n) 
#define nextChar(n) scanf("%c",&n)
#define nextString(n) scanf("%s",tmp);n=tmp

// values
template<typename T> T INF(){assert(false);};
template<> int INF<int>(){return 1<<28;};
template<> ll INF<ll>(){return 1LL<<58;};
template<> float INF<float>(){return 1e10;};
template<> double INF<double>(){return 1e16;};
template<> long double INF<long double>(){return 1e16;};

template<class T> T EPS(){assert(false);};
template<> int EPS<int>(){return 1;};
template<> ll EPS<ll>(){return 1LL;};
template<> float EPS<float>(){return 1e-8;};
template<> double EPS<double>(){return 1e-8;};
template<> long double EPS<long double>(){return 1e-8;};

template<typename T,typename U> T pmod(T v,U M){return (v%M+M)%M;}


namespace _double_tmpl{
    typedef double D;
    
    static constexpr D Ae=0;
    D A(D a,D b){return a+b;}D Ainv(D a){return -a;}
    D S(D a,D b){return A(a,Ainv(b));}
    
    static constexpr D Me=1;
    D M(D a,D b){return a*b;}D Minv(D a){return 1.0/a;};

    int sig(D a,D b=0){return a<b-EPS<D>()?-1:a>b+EPS<D>()?1:0;}
    template<typename T> bool eq(const T& a,const T& b){return sig(abs(a-b))==0;}

    D pfmod(D v,D MOD=2*M_PI){return fmod(fmod(v,MOD)+MOD,MOD);}
    
    //[0,PI)
    D AbsArg(D a){
        D ret=pfmod(max(a,-a),2*M_PI);return min(ret,2*M_PI-ret);
    }
}
using namespace _double_tmpl;

namespace _P{
    // using namespace _double_tmpl;
    typedef complex<D> P,Vec;
    const P O=P(0,0);
#define X real()
#define Y imag()
    istream& operator >> (istream& is,complex<D>& p){
        D x,y;is >> x >> y;p=P(x,y);return is;
    }
    bool compX (const P& a,const P& b){return !eq(a.X,b.X)?sig(a.X,b.X)<0:sig(a.Y,b.Y)<0;}
    bool compY (const P& a,const P& b){return !eq(a.Y,b.Y)?sig(a.Y,b.Y)<0:sig(a.X,b.X)<0;}

    // a×b
    D cross(const Vec& a,const Vec& b){return imag(conj(a)*b);}
    // a・b
    D dot(const Vec&a,const Vec& b) {return real(conj(a)*b);}

    int ccw(const P& a,P b,P c){
        b -= a; c -= a;
        if (sig(cross(b,c))>0)   return +1;       // counter clockwise
        if (sig(cross(b,c))<0)   return -1;       // clockwise
        if (sig(dot(b,c)) < 0)     return +2;       // c--a--b on line
        if (sig(norm(b),norm(c))<0) return -2;       // a--b--c on line
        return 0;
    }

    // 最近点対
    // O(n logn)
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1093043
    D closestPair(vector<P>& ps,int l,int r){
        if(r-l<2)return INF<D>();
        D res=min(closestPair(ps,l,(l+r)/2),closestPair(ps,(l+r)/2,r));
        
        vector<P> ips;FOR(i,l,r)if(abs(ps[i].X - ps[(l+r)/2].X)<res)ips.push_back(ps[i]);
        sort(ALL(ips),compY);
        
        REP(i,ips.size())for(int j=i-10;j<i;j++)if(j>=0)
            res=min(res,abs(ips[i]-ips[j]));

        return res;
    }
    D closestPair(vector<P>& ps){return closestPair(ps,0,ps.size());}


    // verified by 
    // 事前にs-g
    // O-s → O-gの回転方向に関してソート．
    // (同角度の場合、距離が遠い方が前)
    P s,g;
    bool CompArg(const P& p1,const P&p2){
        if(abs(ccw(O,p1,p2))!=1)return abs(p1)>abs(p2);//sameline
        return ccw(O,p1,p2)==ccw(O,s,g);
    }

    //!!
    //角度ソート
    P dir;//基準方向
    bool Comp(const P& p1,const P&p2){
        if(sig(pfmod(arg(p1)-arg(dir)),pfmod(arg(p2)-arg(dir)))==0)return abs(p1)>abs(p2);
        return sig(pfmod(arg(p1)-arg(dir)),pfmod(arg(p2)-arg(dir)));
    }

}
using namespace _P;

namespace std{
    bool operator < (const P& a,const P& b){return _P::compX(a,b);}
    bool operator == (const P& a,const P& b){return eq(a,b);}
};

namespace _L{
    struct L : public vector<P> {
        P vec() const {return this->at(1)-this->at(0);}
        L(const P &a, const P &b){push_back(a); push_back(b);}
        L(){push_back(P(0,0));push_back(P(0,0));}
    };
    istream& operator >> (istream& is,L& l){P s,t;is >> s >> t;l=L(s,t);return is;}

    bool isIntersectLL(const L &l, const L &m) {
        return sig(cross(l.vec(), m.vec()))!=0 || // non-parallel
        sig(cross(l.vec(), m[0]-l[0])) ==0;   // same line
    }
    bool isIntersectLS(const L &l, const L &s) {
      return sig(cross(l.vec(), s[0]-l[0])*       // s[0] is left of l
             cross(l.vec(), s[1]-l[0]))<=0; // s[1] is right of l
    }
    bool isIntersectLP(const L &l, const P &p) {
        return sig(cross(l[1]-p, l[0]-p))==0;
    }

    // verified by ACAC003 B
    // http://judge.u-aizu.ac.jp/onlinejudge/creview.jsp?rid=899178&cid=ACAC003
    bool isIntersectSS(const L &s, const L &t) {
      return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
             ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
    }
    bool isIntersectSP(const L &s, const P &p) {
      return sig(abs(s[0]-p)+abs(s[1]-p),abs(s[1]-s[0])) <=0; // triangle inequality
    }

    // 直線へ射影した時の点
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1092212
    P projection(const L &l, const P &p) {
      D t = dot(p-l[0],l.vec()) / norm(l.vec());
      return l[0] + t * l.vec();
    }
    //対称な点
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1092214
    P reflection(const L &l, const P &p) {
      return p + 2.0 * (projection(l, p) - p);
    }
    D distanceLP(const L &l, const P &p) {
      return abs(p - projection(l, p));
    }
    D distanceLL(const L &l, const L &m) {
      return isIntersectLL(l, m) ? 0 : distanceLP(l, m[0]);
    }
    D distanceLS(const L &l, const L &s) {
        if (isIntersectLS(l, s)) return 0;
        return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
    }
    D distanceSP(const L &s, const P &p) {
      const P r = projection(s, p);
      if (isIntersectSP(s, r)) return abs(r - p);
      return min(abs(s[0] - p), abs(s[1] - p));
    }
    D distanceSS(const L &s, const L &t) {
        if (isIntersectSS(s, t)) return 0;
        return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
                 min(distanceSP(t, s[0]), distanceSP(t, s[1])));
    }

    // 交点計算
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1092231
    P crosspoint(const L &l, const L &m) {
      D A = cross(l.vec(), m.vec()),B = cross(l.vec(), l[1] - m[0]);
      if (sig(A)==0 && sig(B)==0) return m[0]; // same line
      assert(sig(A)!=0);//err -> 交点を持たない．
      return m[0] + B / A * (m[1] - m[0]);
    }
}
using namespace _L;


class Main{
    public:
    void run(){
        int N;cin >> N;
        vector<L> ls(N);
        REP(i,N){
            cin >> ls[i][0] >> ls[i][1];
            if(ls[i][0].X>ls[i][1].X)swap(ls[i][0],ls[i][1]);
        }
        if(N*2>101*101){
            cout <<0<<endl;return;
        }

        D res=INF<D>();
        sort(ALL(ls),[](L l,L r){
            return l[0].X<r[0].X;
        });
        REP(i,N)for(int j=i+1;j<N;j++){
            if(ls[j][0].X-ls[i][1].X >res)break;
            res=min(res,distanceSS(ls[i],ls[j]));
        }
        cout << res << endl;
    
    }
};

int main(){
    cout <<fixed<<setprecision(20);
    cin.tie(0);
    ios::sync_with_stdio(false);
    Main().run();
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 7596
final_rank: 6

code_snippet: #include <cassert>// c
#include <iostream>// io
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>// container
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <algorithm>// other
#include <complex>
#include <numeric>
#include <functional>
#include <random>
#include <regex>
using namespace std;

typedef long long ll;

#define ALL(c) (begin(c)),(end(c))
#define REP(i,n) FOR(i,0,n)
#define REPr(i,n) FORr(i,0,n)
#define FOR(i,l,r) for(int i=(int)(l);i<(int)(r);++i)
#define FORr(i,l,r) for(int i=(int)(r)-1;i>=(int)(l);--i)
#define EACH(it,o) for(auto it = (o).begin(); it != (o).end(); ++it)
#define IN(l,v,r) ((l)<=(v) && (v)<(r))
#define UNIQUE(v) v.erase(unique(ALL(v)),v.end())
//debug
#define DUMP(x)  cerr << #x << " = " << (x)
#define LINE()    cerr<< " (L" << __LINE__ << ")"

class range {
private:
    struct Iter{
        int v;
        int operator*(){return v;}
        bool operator!=(Iter& itr) {return v < itr.v;}
        void operator++() {++v;}
    };
    Iter i, n;
public:
    range(int n) : i({0}), n({n}) {}
    range(int i, int n) : i({i}), n({n}) {}
    Iter& begin() {return i;}
    Iter& end() {return n;}
};

//output
template<typename T> ostream& operator << (ostream& os, const vector<T>& as){REP(i,as.size()){if(i!=0)os<<" "; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const vector<vector<T>>& as){REP(i,as.size()){if(i!=0)os<<endl; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const set<T>& ss){for(auto a:ss){if(a!=ss.begin())os<<" "; os<<a;}return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const pair<T1,T2>& p){os<<p.first<<" "<<p.second;return os;}
template<typename K,typename V> ostream& operator << (ostream& os, const map<K,V>& m){bool isF=true;for(auto& p:m){if(!isF)os<<endl;os<<p;isF=false;}return os;}
template<typename T1> ostream& operator << (ostream& os, const tuple<T1>& t){os << get<0>(t);return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const tuple<T1,T2>& t){os << get<0>(t)<<" "<<get<1>(t);return os;}
template<typename T1,typename T2,typename T3> ostream& operator << (ostream& os, const tuple<T1,T2,T3>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t);return os;}
template<typename T1,typename T2,typename T3,typename T4,typename T5,typename T6,typename T7> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4,T5,T6,T7>& t){os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t)<<" "<<get<4>(t)<<" "<<get<5>(t)<<" "<<get<6>(t);return os;}

//input
char tmp[1000];
#define nextInt(n) scanf("%d",&n)
#define nextLong(n) scanf("%lld",&n) //I64d
#define nextDouble(n) scanf("%lf",&n) 
#define nextChar(n) scanf("%c",&n)
#define nextString(n) scanf("%s",tmp);n=tmp

// values
template<typename T> T INF(){assert(false);};
template<> int INF<int>(){return 1<<28;};
template<> ll INF<ll>(){return 1LL<<58;};
template<> double INF<double>(){return 1e16;};
template<> long double INF<long double>(){return 1e16;};

template<class T> T EPS(){assert(false);};
template<> int EPS<int>(){return 1;};
template<> ll EPS<ll>(){return 1LL;};
template<> double EPS<double>(){return 1e-8;};
template<> long double EPS<long double>(){return 1e-8;};

template<typename T,typename U> T pmod(T v,U M){return (v%M+M)%M;}


namespace _double_tmpl{
    typedef long double D;
    
    static constexpr D Ae=0;
    D A(D a,D b){return a+b;}D Ainv(D a){return -a;}
    D S(D a,D b){return A(a,Ainv(b));}
    
    static constexpr D Me=1;
    D M(D a,D b){return a*b;}D Minv(D a){return 1.0/a;};

    int sig(D a,D b=0){return a<b-EPS<D>()?-1:a>b+EPS<D>()?1:0;}
    template<typename T> bool eq(const T& a,const T& b){return sig(abs(a-b))==0;}

    D pfmod(D v,D MOD=2*M_PI){return fmod(fmod(v,MOD)+MOD,MOD);}
    
    //[0,PI)
    D AbsArg(D a){
        D ret=pfmod(max(a,-a),2*M_PI);return min(ret,2*M_PI-ret);
    }
}
using namespace _double_tmpl;

namespace _P{
    // using namespace _double_tmpl;
    typedef complex<D> P,Vec;
    const P O=P(0,0);
#define X real()
#define Y imag()
    istream& operator >> (istream& is,complex<D>& p){
        D x,y;is >> x >> y;p=P(x,y);return is;
    }
    bool compX (const P& a,const P& b){return !eq(a.X,b.X)?sig(a.X,b.X)<0:sig(a.Y,b.Y)<0;}
    bool compY (const P& a,const P& b){return !eq(a.Y,b.Y)?sig(a.Y,b.Y)<0:sig(a.X,b.X)<0;}

    // a×b
    D cross(const Vec& a,const Vec& b){return imag(conj(a)*b);}
    // a・b
    D dot(const Vec&a,const Vec& b) {return real(conj(a)*b);}

    int ccw(const P& a,P b,P c){
        b -= a; c -= a;
        if (sig(cross(b,c))>0)   return +1;       // counter clockwise
        if (sig(cross(b,c))<0)   return -1;       // clockwise
        if (sig(dot(b,c)) < 0)     return +2;       // c--a--b on line
        if (sig(norm(b),norm(c))<0) return -2;       // a--b--c on line
        return 0;
    }

    // 最近点対
    // O(n logn)
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1093043
    D closestPair(vector<P>& ps,int l,int r){
        if(r-l<2)return INF<D>();
        D res=min(closestPair(ps,l,(l+r)/2),closestPair(ps,(l+r)/2,r));
        
        vector<P> ips;FOR(i,l,r)if(abs(ps[i].X - ps[(l+r)/2].X)<res)ips.push_back(ps[i]);
        sort(ALL(ips),compY);
        
        REP(i,ips.size())for(int j=i-10;j<i;j++)if(j>=0)
            res=min(res,abs(ips[i]-ips[j]));

        return res;
    }
    D closestPair(vector<P>& ps){return closestPair(ps,0,ps.size());}


    // verified by 
    // 事前にs-g
    // O-s → O-gの回転方向に関してソート．
    // (同角度の場合、距離が遠い方が前)
    P s,g;
    bool CompArg(const P& p1,const P&p2){
        if(abs(ccw(O,p1,p2))!=1)return abs(p1)>abs(p2);//sameline
        return ccw(O,p1,p2)==ccw(O,s,g);
    }

    //!!
    //角度ソート
    P dir;//基準方向
    bool Comp(const P& p1,const P&p2){
        if(sig(pfmod(arg(p1)-arg(dir)),pfmod(arg(p2)-arg(dir)))==0)return abs(p1)>abs(p2);
        return sig(pfmod(arg(p1)-arg(dir)),pfmod(arg(p2)-arg(dir)));
    }

}
using namespace _P;

namespace std{
    bool operator < (const P& a,const P& b){return _P::compX(a,b);}
    bool operator == (const P& a,const P& b){return eq(a,b);}
};

namespace _L{
    struct L : public vector<P> {
        P vec() const {return this->at(1)-this->at(0);}
        L(const P &a, const P &b){push_back(a); push_back(b);}
        L(){push_back(P(0,0));push_back(P(0,0));}
    };
    istream& operator >> (istream& is,L& l){P s,t;is >> s >> t;l=L(s,t);return is;}

    bool isIntersectLL(const L &l, const L &m) {
        return sig(cross(l.vec(), m.vec()))!=0 || // non-parallel
        sig(cross(l.vec(), m[0]-l[0])) ==0;   // same line
    }
    bool isIntersectLS(const L &l, const L &s) {
      return sig(cross(l.vec(), s[0]-l[0])*       // s[0] is left of l
             cross(l.vec(), s[1]-l[0]))<=0; // s[1] is right of l
    }
    bool isIntersectLP(const L &l, const P &p) {
        return sig(cross(l[1]-p, l[0]-p))==0;
    }

    // verified by ACAC003 B
    // http://judge.u-aizu.ac.jp/onlinejudge/creview.jsp?rid=899178&cid=ACAC003
    bool isIntersectSS(const L &s, const L &t) {
      return ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0 &&
             ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0;
    }
    bool isIntersectSP(const L &s, const P &p) {
      return sig(abs(s[0]-p)+abs(s[1]-p),abs(s[1]-s[0])) <=0; // triangle inequality
    }

    // 直線へ射影した時の点
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1092212
    P projection(const L &l, const P &p) {
      D t = dot(p-l[0],l.vec()) / norm(l.vec());
      return l[0] + t * l.vec();
    }
    //対称な点
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1092214
    P reflection(const L &l, const P &p) {
      return p + 2.0L * (projection(l, p) - p);
    }
    D distanceLP(const L &l, const P &p) {
      return abs(p - projection(l, p));
    }
    D distanceLL(const L &l, const L &m) {
      return isIntersectLL(l, m) ? 0 : distanceLP(l, m[0]);
    }
    D distanceLS(const L &l, const L &s) {
        if (isIntersectLS(l, s)) return 0;
        return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
    }
    D distanceSP(const L &s, const P &p) {
      const P r = projection(s, p);
      if (isIntersectSP(s, r)) return abs(r - p);
      return min(abs(s[0] - p), abs(s[1] - p));
    }
    D distanceSS(const L &s, const L &t) {
        if (isIntersectSS(s, t)) return 0;
        return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
                 min(distanceSP(t, s[0]), distanceSP(t, s[1])));
    }

    // 交点計算
    // verified by AOJLIB
    // http://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=1092231
    P crosspoint(const L &l, const L &m) {
      D A = cross(l.vec(), m.vec()),B = cross(l.vec(), l[1] - m[0]);
      if (sig(A)==0 && sig(B)==0) return m[0]; // same line
      assert(sig(A)!=0);//err -> 交点を持たない．
      return m[0] + B / A * (m[1] - m[0]);
    }
}
using namespace _L;

class Main{
    public:
    void run(){
        int N;cin >> N;
        vector<L> ls(N);
        REP(i,N)cin >> ls[i][0] >> ls[i][1];
        if(N*2>10000){
            cout <<0<<endl;return;
        }

        D res=INF<D>();
        REP(i,N)REP(j,N)if(i!=j){
            res=min(res,distanceSS(ls[i],ls[j]));
        }

        cout << res << endl;
    
    }
};

int main(){
    cout <<fixed<<setprecision(20);
    cin.tie(0);
    ios::sync_with_stdio(false);
    Main().run();
    return 0;
}
accuracy: 0.967741935483871
time_ms: 60
memory_kb: 10500
final_rank: 20

code_snippet: #include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
const double EPS = 1e-10;
const double INF = 1e+10;
const double PI = acos(-1);
int sig(double r) { return (r < -EPS) ? -1 : (r > +EPS) ? +1 : 0; }
inline double ABS(double a){return max(a,-a);}
struct Pt {
	double x, y;
	Pt() {}
	Pt(double x, double y) : x(x), y(y) {}
	Pt operator+(const Pt &a) const { return Pt(x + a.x, y + a.y); }
	Pt operator-(const Pt &a) const { return Pt(x - a.x, y - a.y); }
	Pt operator*(const Pt &a) const { return Pt(x * a.x - y * a.y, x * a.y + y * a.x); }
	Pt operator-() const { return Pt(-x, -y); }
	Pt operator*(const double &k) const { return Pt(x * k, y * k); }
	Pt operator/(const double &k) const { return Pt(x / k, y / k); }
	double ABS() const { return sqrt(x * x + y * y); }
	double abs2() const { return x * x + y * y; }
	double arg() const { return atan2(y, x); }
	double dot(const Pt &a) const { return x * a.x + y * a.y; }
	double det(const Pt &a) const { return x * a.y - y * a.x; }
};
double tri(const Pt &a, const Pt &b, const Pt &c) { return (b - a).det(c - a); }
int iSP(Pt a, Pt b, Pt c) {
	int s = sig((b - a).det(c - a));
	if (s) return s;
	if (sig((b - a).dot(c - a)) < 0) return -2; // c-a-b
	if (sig((a - b).dot(c - b)) < 0) return +2; // a-b-c
	return 0;
}
int iLL(Pt a, Pt b, Pt c, Pt d) {
	if (sig((b - a).det(d - c))) return 1; // intersect
	if (sig((b - a).det(c - a))) return 0; // parallel
	return -1; // correspond
}
bool iLS(Pt a, Pt b, Pt c, Pt d) {
	return (sig(tri(a, b, c)) * sig(tri(a, b, d)) <= 0);
}
bool iSS(Pt a, Pt b, Pt c, Pt d) {
	return (iSP(a, b, c) * iSP(a, b, d) <= 0 && iSP(c, d, a) * iSP(c, d, b) <= 0);
}
bool iSSstrict(Pt a, Pt b, Pt c, Pt d) {
	return (sig(tri(a, b, c)) * sig(tri(a, b, d)) < 0 && sig(tri(c, d, a)) * sig(tri(c, d, b)) < 0);
}
Pt pLL(Pt a, Pt b, Pt c, Pt d) {
	b = b - a; d = d - c; return a + b * (c - a).det(d) / b.det(d);
}
double dLP(Pt a, Pt b, Pt c) {
	return ABS(tri(a, b, c)) / (b - a).ABS();
}
double dSP(Pt a, Pt b, Pt c) {
	if (sig((b - a).dot(c - a)) <= 0) return (c - a).ABS();
	if (sig((a - b).dot(c - b)) <= 0) return (c - b).ABS();
	return ABS(tri(a, b, c)) / (b - a).ABS();
}
double dLL(Pt a, Pt b, Pt c, Pt d) {
	return iLL(a, b, c, d) ? 0 : dLP(a, b, c);
}
double dLS(Pt a, Pt b, Pt c, Pt d) {
	return iLS(a, b, c, d) ? 0 : min(dLP(a, b, c), dLP(a, b, d));
}
double dSS(Pt a, Pt b, Pt c, Pt d) {
	return iSS(a, b, c, d) ? 0 : min(min(dSP(a, b, c), dSP(a, b, d)), min(dSP(c, d, a), dSP(c, d, b)));
}
Pt p[5300];
Pt q[5300];
int main(){
	int a;
	scanf("%d",&a);
	if(a>5300){
		printf("0\n");return 0;
	}
	for(int i=0;i<a;i++){
		int X1,Y1,X2,Y2;
		scanf("%d%d%d%d",&X1,&Y1,&X2,&Y2);
		p[i]=Pt(X1,Y1);
		q[i]=Pt(X2,Y2);
	}
	double ret=9999999;
	for(int i=0;i<a;i++){
		for(int j=i+1;j<a;j++){
			ret=min(ret,dSS(p[i],q[i],p[j],q[j]));
		}
	}
	printf("%.12f\n",ret);
}
accuracy: 1
time_ms: 520
memory_kb: 1228
final_rank: 3

code_snippet: #include<iostream>
#include<complex>
#include<algorithm>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};

const D EPS = 1e-8;

int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return !sig(norm(a - b));}
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  bool operator<(L a, L b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

P vec(L a) {return a.b - a.a;}

enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (near(a, c) || near(b, c)) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

bool iSS(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

D dLP(L l, P p) {return abs(det(vec(l), p - l.a) / vec(l));}
D dSP(L s, P p) {
  if (dot(vec(s), p - s.a) < 0) return abs(p - s.a);
  if (dot(vec(s), p - s.b) > 0) return abs(p - s.b);
  return dLP(s, p);
}
D dSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dSP(a, b.a), dSP(a, b.b)), min(dSP(b, a.a), dSP(b, a.b)));}

int main() {
  int n;
  cin >> n;
  if (n > 10000) {
    cout << 0 << endl;
    return 0;
  }
  L s[n];
  rep (i, n) {
    D x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    s[i] = (L){P(x1, y1), P(x2, y2)};
    if (x1 > x2) swap(s[i].a, s[i].b);
  }
  sort(s, s + n);
  D res = 1e9;
  rep (i, n) for (int j = i - 1; j >= 0; --j) {
    if (sig(s[i].a.X - res, s[j].b.X) > 0) continue;
    res = min(res, dSS(s[i], s[j]));
  }
  printf("%.12Lf\n", res);
}
accuracy: 1
time_ms: 480
memory_kb: 1584
final_rank: 2

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define EPS (1e-7)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define MAX 100100

using namespace std;

// Library

class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator == (const Segment& p)const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}


bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}

bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

// Library

int N;
Segment seg[MAX];

int main(){
  cin >> N;
  rep(i,N)cin >> seg[i].p1.x >> seg[i].p1.y >> seg[i].p2.x >> seg[i].p2.y;

  cout << setiosflags(ios::fixed) << setprecision(10);

  if( N >= 5100 ){
    cout << 0 << endl;
    return 0;
  }

  double ans = IINF;
  rep(i,N){
    REP(j,i+1,N){
      double dist = distanceSS(seg[i],seg[j]);
      if( equals(ans,dist) || dist > ans ) continue;
      ans = dist;
    }
  }
  cout << ans << endl;

  return 0;
}
accuracy: 0.967741935483871
time_ms: 90
memory_kb: 4420
final_rank: 14

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define EPS (1e-7)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define MAX 100100

using namespace std;

// Library

class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator == (const Segment& p)const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}


bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}

bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

// Library

int N;
Segment seg[MAX];

int main(){
  cin >> N;
  rep(i,N)cin >> seg[i].p1.x >> seg[i].p1.y >> seg[i].p2.x >> seg[i].p2.y;

  cout << setiosflags(ios::fixed) << setprecision(10);

  if( N >= 5002 ){
    cout << 0 << endl;
    return 0;
  }

  double ans = IINF;
  rep(i,N){
    REP(j,i+1,N){
      double dist = distanceSS(seg[i],seg[j]);
      if( equals(ans,dist) || dist > ans ) continue;
      ans = dist;
    }
  }
  cout << ans << endl;

  return 0;
}
accuracy: 0.967741935483871
time_ms: 90
memory_kb: 4424
final_rank: 17

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define EPS (1e-9)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define MAX 100100

using namespace std;

// Library

class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator == (const Segment& p)const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}


bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}

bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

// Library

int N;
Segment seg[MAX];

int main(){
  cin >> N;
  rep(i,N)cin >> seg[i].p1.x >> seg[i].p1.y >> seg[i].p2.x >> seg[i].p2.y;
  if( N >= 5002 ){
    cout << 0 << endl;
    return 0;
  }

  double ans = IINF;
  rep(i,N){
    REP(j,i+1,N){
      double dist = distanceSS(seg[i],seg[j]);
      if( equals(ans,dist) || dist > ans ) continue;
      ans = dist;
    }
  }
  cout << setiosflags(ios::fixed) << setprecision(10) << ans << endl;

  return 0;
}
accuracy: 0.967741935483871
time_ms: 90
memory_kb: 4420
final_rank: 14

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define IINF (INT_MAX)
#define EPS (1e-5)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define MAX 100100

using namespace std;

// Library

class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator == (const Segment& p)const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}


bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}

bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

// Library

int N;
Segment seg[MAX];

int main(){
  cin >> N;
  rep(i,N)cin >> seg[i].p1.x >> seg[i].p1.y >> seg[i].p2.x >> seg[i].p2.y;
  if( N >= 5002 ){
    cout << 0 << endl;
    return 0;
  }

  double ans = IINF;
  rep(i,N){
    REP(j,i+1,N){
      double dist = distanceSS(seg[i],seg[j]);
      if( equals(ans,dist) || dist > ans ) continue;
      ans = dist;
    }
  }
  cout << setiosflags(ios::fixed) << setprecision(10) << ans << endl;

  return 0;
}
accuracy: 0.967741935483871
time_ms: 90
memory_kb: 4420
final_rank: 14