Problem:
Closest Pair
For given
n
points in metric space, find the distance of the closest points.
Input
n
x
0
y
0
x
1
y
1
:
x
n-1
y
n-1
The first integer
n
is the number of points.
In the following
n
lines, the coordinate of the
i
-th point is given by two real numbers
x
i
and
y
i
. Each value is a real number with at most 6 digits after the decimal point.
Output
Print the distance in a line. The output values should be in a decimal fraction with an error less than 0.000001.
Constraints
2 ≤
n
≤ 100,000
-100 ≤
x
,
y
≤ 100
Sample Input 1
2
0.0 0.0
1.0 0.0
Sample Output 1
1.000000
Sample Input 2
3
0.0 0.0
2.0 0.0
1.0 1.0
Sample Output 2
1.41421356237

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define ov4(a, b, c, d, name, ...) name
#define rep3(i, a, b, c) for(ll i = (a); i < (b); i += (c))
#define rep2(i, a, b) rep3(i, a, b, 1)
#define rep1(i, n) rep2(i, 0, n)
#define rep0(n) rep1(aaaaa, n)
#define rep(...) ov4(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define per(i, a, b) for(ll i = (a)-1; i >= (b); i--)
#define fore(e, v) for(auto&& e : v)
#define all(a) begin(a), end(a)
#define si(a) (int)(size(a))
#define lb(v, x) (lower_bound(all(v), x) - begin(v))
#define eb emplace_back

template<typename T, typename S> bool chmin(T& a, const S& b) { return a > b ? a = b, 1 : 0; }
template<typename T, typename S> bool chmax(T& a, const S& b) { return a < b ? a = b, 1 : 0; }

const int INF = 1e9 + 100;
const ll INFL = 3e18 + 100;

#define i128 __int128_t

struct _ {
   _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

template<class T> int sgn(T x) { return (x > 0) - (x < 0); }
template<class T>
struct Point {
    typedef Point P;
    T x, y;
    explicit Point(T x=0, T y=0) : x(x), y(y) {}
    bool operator<(P p) const { return tie(x, y) < tie(p.x, p.y); }
    bool operator==(P p) const { return tie(x, y) == tie(p.x, p.y); }
    P operator+(P p) const { return P(x + p.x, y + p.y); }
    P operator-(P p) const { return P(x - p.x, y - p.y); }
    P operator*(T d) const { return P(x * d, y * d); }
    P operator/(T d) const { return P(x / d, y / d); }
    T dot(P p) const { return x * p.x + y * p.y; }
    T cross(P p) const { return x * p.y - y * p.x; }
    T cross(P a, P b) const { return (a - *this).cross(b - *this); }
    T dist2() const { return x*x + y*y; }
    double dist() const { return sqrt((double)dist2()); }
    P perp() const { return P(-y, x); }
};

template<class P>
P lineProj(P a, P b, P p, bool refl=false) {
    P v = b - a;
    return p - v.perp() * (1 + refl) * v.cross(p - a) / v.dist2();
}

template<class P>
bool onSegment(P s, P e, P p) {
    return p.cross(s, e) == 0 and (s - p).dot(e - p) <= 0;
}

template<class P>
vector<P> segInter(P a, P b, P c, P d) {
    auto oa = c.cross(d, a), ob = c.cross(d, b),
         oc = a.cross(b, c), od = a.cross(b, d);
    if (sgn(oa) * sgn(ob) < 0 and sgn(oc) * sgn(od) < 0) {
        return {(a * ob - b * oa) / (ob - oa)};
    }
    set<P> s;
    if (onSegment(c, d, a)) s.insert(a);
    if (onSegment(c, d, b)) s.insert(b);
    if (onSegment(a, b, c)) s.insert(c);
    if (onSegment(a, b, d)) s.insert(d);
    return {all(s)};
}

template<class P>
double segDist(P s, P e, P p) {
    if (s == e) return (p - s).dist();
    auto d = (s - e).dist2(), t = min(d, max(.0, (p - s).dot(e - s)));
    return ((p - s) * d - (e - s) * t).dist() / d;
}

template<class P>
double segDist(P s1, P e1, P s2, P e2) {
    if (!segInter(s1, e1, s2, e2).empty()) return 0;
    auto a = min(segDist(s1, e1, s2), segDist(s1, e1, e2));
    auto b = min(segDist(s2, e2, s1), segDist(s2, e2, e1));
    return min(a, b);
}

template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
    auto d = (e1 - s2).cross(e2 - s2);
    if(d == 0) {
        return {-(s1.cross(e1, s2) == 0), P(0, 0)};
    }
    auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
    return {1, (s1 * p + e1 * q) / d};
}

template<class T>
T polygonArea2(vector<Point<T>> &v) {
    if (si(v) <= 2) return 0; // 
    T a = v.back().cross(v[0]);
    rep(i, si(v) - 1) a += v[i].cross(v[i + 1]);
    return a;
}

using P = Point<ll>;

// speed star library
// typedef Point<long double> P;
vector<P> convex_hull(vector<P> pts) {
    int n = si(pts), k = 0;
    if (n <= 2) return pts;
    sort(all(pts));
    vector<P> ch(2 * n);
    for(int i = 0; i < n; ch[k++] = pts[i++]) {
        while(k >= 2 and (ch[k - 1] - ch[k - 2]).cross(pts[i] - ch[k - 1]) <= -1.0e-14) --k;
    }
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = pts[i--]) {
        while(k >= t and (ch[k - 1] - ch[k - 2]).cross(pts[i] - ch[k - 1]) <= -1.0e-14) --k;
    }
    ch.resize(k - 1);
    return ch;
}

array<P, 2> hullDiameter(vector<P> S) {
    int n = si(S), j = n < 2 ? 0 : 1;
    pair<long double, array<P, 2>> res({0, {S[0], S[0]}});
    rep(i, j) {
        for (;; j = (j + 1) % n) {
            res = max(res, {(S[i] - S[j]).dist2(), {S[i], S[j]}});
            if ((S[(j + 1) % n] - S[j]).cross(S[i + 1] - S[i]) >= 1.0e-14) break;
        }
    }
    return res.second;
}

// typedef Point<double> P;
vector<P> polygonCut(const vector<P> &poly, P s, P e) {
    vector<P> res;
    rep(i, si(poly)) {
        P cur = poly[i], prev = i ? poly[i - 1] : poly.back();
        auto a = s.cross(e, cur), b = s.cross(e, prev);
        if ((a < 0) != (b < 0)) res.push_back(cur + (prev - cur) * (a / (a - b)));
        if (a < 0) res.push_back(cur);
    }
    return res;
}

template<class P>
bool inPolygon(vector<P> &p, P a, bool strict = true) {
    int cnt = 0, n = si(p);
    rep(i, n) {
        P q = p[(i + 1) % n];
        if (onSegment(p[i], q, a)) return !strict;
        cnt ^= ((a.y < p[i].y) - (a.y < q.y)) * a.cross(p[i], q) > 0;
    }
    return cnt;
}

// typedef Point<ll> P;
pair<P, P> closest(vector<P> v) {
    assert(si(v) > 1);
    set<P> S;
    sort(all(v), [](P a, P b) { return a.y < b.y; });
    pair<ll, pair<P, P>> ret{LLONG_MAX, {P(), P()}};
    int j = 0;
    fore(p, v) {
        P d{1 + (ll)sqrt(ret.first), 0};
        while (v[j].y <= p.y - d.x) S.erase(v[j++]);
        auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d);
        for (; lo != hi; ++lo) ret = min(ret, {(*lo - p).dist2(), {*lo, p}});
        S.insert(p);
    }
    return ret.second;
} 

using P = Point<ll>;

ll conv(string s) {
    s += "000000";
    ll res = 0;
    int cnt = 1;
    fore(c, s) {
        if (isdigit(c)) {
            res *= 10;
            res += c - '0';
            cnt++;
            if (cnt == 0) break;
        } if (c == '.') {
            cnt = -6;
        }
    }
    if (s[0] == '-') res *= -1;
    return res;
}

int main() {
    int n;
    cin >> n;
    vector<P> v;
    rep(i, n) {
        string s, t;
        cin >> s >> t;
        v.push_back(P(conv(s), conv(t)));
    }

    cout << setprecision(15) << fixed;
    auto res = closest(v);
    cout << (double)(res.first - res.second).dist() / 1e6 << endl;
}
accuracy: 1
time_ms: 40
memory_kb: 11880
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi vector<int>
#define vl vector<ll>
#define ov4(a, b, c, d, name, ...) name
#define rep3(i, a, b, c) for(ll i = (a); i < (b); i += (c))
#define rep2(i, a, b) rep3(i, a, b, 1)
#define rep1(i, n) rep2(i, 0, n)
#define rep0(n) rep1(aaaaa, n)
#define rep(...) ov4(__VA_ARGS__, rep3, rep2, rep1, rep0)(__VA_ARGS__)
#define per(i, a, b) for(ll i = (a)-1; i >= (b); i--)
#define fore(e, v) for(auto&& e : v)
#define all(a) begin(a), end(a)
#define si(a) (int)(size(a))
#define lb(v, x) (lower_bound(all(v), x) - begin(v))
#define eb emplace_back

template<typename T, typename S> bool chmin(T& a, const S& b) { return a > b ? a = b, 1 : 0; }
template<typename T, typename S> bool chmax(T& a, const S& b) { return a < b ? a = b, 1 : 0; }

const int INF = 1e9 + 100;
const ll INFL = 3e18 + 100;

#define i128 __int128_t

struct _ {
   _() { cin.tie(0)->sync_with_stdio(0), cout.tie(0); }
} __;

template<class T> int sgn(T x) { return (x > 0) - (x < 0); }
template<class T>
struct Point {
    typedef Point P;
    T x, y;
    explicit Point(T x=0, T y=0) : x(x), y(y) {}
    bool operator<(P p) const { return tie(x, y) < tie(p.x, p.y); }
    bool operator==(P p) const { return tie(x, y) == tie(p.x, p.y); }
    P operator+(P p) const { return P(x + p.x, y + p.y); }
    P operator-(P p) const { return P(x - p.x, y - p.y); }
    P operator*(T d) const { return P(x * d, y * d); }
    P operator/(T d) const { return P(x / d, y / d); }
    T dot(P p) const { return x * p.x + y * p.y; }
    T cross(P p) const { return x * p.y - y * p.x; }
    T cross(P a, P b) const { return (a - *this).cross(b - *this); }
    T dist2() const { return x*x + y*y; }
    double dist() const { return sqrt((double)dist2()); }
    P perp() const { return P(-y, x); }
};

template<class P>
P lineProj(P a, P b, P p, bool refl=false) {
    P v = b - a;
    return p - v.perp() * (1 + refl) * v.cross(p - a) / v.dist2();
}

template<class P>
bool onSegment(P s, P e, P p) {
    return p.cross(s, e) == 0 and (s - p).dot(e - p) <= 0;
}

template<class P>
vector<P> segInter(P a, P b, P c, P d) {
    auto oa = c.cross(d, a), ob = c.cross(d, b),
         oc = a.cross(b, c), od = a.cross(b, d);
    if (sgn(oa) * sgn(ob) < 0 and sgn(oc) * sgn(od) < 0) {
        return {(a * ob - b * oa) / (ob - oa)};
    }
    set<P> s;
    if (onSegment(c, d, a)) s.insert(a);
    if (onSegment(c, d, b)) s.insert(b);
    if (onSegment(a, b, c)) s.insert(c);
    if (onSegment(a, b, d)) s.insert(d);
    return {all(s)};
}

template<class P>
double segDist(P s, P e, P p) {
    if (s == e) return (p - s).dist();
    auto d = (s - e).dist2(), t = min(d, max(.0, (p - s).dot(e - s)));
    return ((p - s) * d - (e - s) * t).dist() / d;
}

template<class P>
double segDist(P s1, P e1, P s2, P e2) {
    if (!segInter(s1, e1, s2, e2).empty()) return 0;
    auto a = min(segDist(s1, e1, s2), segDist(s1, e1, e2));
    auto b = min(segDist(s2, e2, s1), segDist(s2, e2, e1));
    return min(a, b);
}

template<class P>
pair<int, P> lineInter(P s1, P e1, P s2, P e2) {
    auto d = (e1 - s2).cross(e2 - s2);
    if(d == 0) {
        return {-(s1.cross(e1, s2) == 0), P(0, 0)};
    }
    auto p = s2.cross(e1, e2), q = s2.cross(e2, s1);
    return {1, (s1 * p + e1 * q) / d};
}

template<class T>
T polygonArea2(vector<Point<T>> &v) {
    if (si(v) <= 2) return 0; // 
    T a = v.back().cross(v[0]);
    rep(i, si(v) - 1) a += v[i].cross(v[i + 1]);
    return a;
}

// speed star library
typedef Point<long double> P;
vector<P> convex_hull(vector<P> pts) {
    int n = si(pts), k = 0;
    if (n <= 2) return pts;
    sort(all(pts));
    vector<P> ch(2 * n);
    for(int i = 0; i < n; ch[k++] = pts[i++]) {
        while(k >= 2 and (ch[k - 1] - ch[k - 2]).cross(pts[i] - ch[k - 1]) <= -1.0e-14) --k;
    }
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = pts[i--]) {
        while(k >= t and (ch[k - 1] - ch[k - 2]).cross(pts[i] - ch[k - 1]) <= -1.0e-14) --k;
    }
    ch.resize(k - 1);
    return ch;
}

array<P, 2> hullDiameter(vector<P> S) {
    int n = si(S), j = n < 2 ? 0 : 1;
    pair<long double, array<P, 2>> res({0, {S[0], S[0]}});
    rep(i, j) {
        for (;; j = (j + 1) % n) {
            res = max(res, {(S[i] - S[j]).dist2(), {S[i], S[j]}});
            if ((S[(j + 1) % n] - S[j]).cross(S[i + 1] - S[i]) >= 1.0e-14) break;
        }
    }
    return res.second;
}

// typedef Point<double> P;
vector<P> polygonCut(const vector<P> &poly, P s, P e) {
    vector<P> res;
    rep(i, si(poly)) {
        P cur = poly[i], prev = i ? poly[i - 1] : poly.back();
        auto a = s.cross(e, cur), b = s.cross(e, prev);
        if ((a < 0) != (b < 0)) res.push_back(cur + (prev - cur) * (a / (a - b)));
        if (a < 0) res.push_back(cur);
    }
    return res;
}

template<class P>
bool inPolygon(vector<P> &p, P a, bool strict = true) {
    int cnt = 0, n = si(p);
    rep(i, n) {
        P q = p[(i + 1) % n];
        if (onSegment(p[i], q, a)) return !strict;
        cnt ^= ((a.y < p[i].y) - (a.y < q.y)) * a.cross(p[i], q) > 0;
    }
    return cnt;
}

using ld = long double;
// typedef Point<ll> P;
pair<P, P> closest(vector<P> v) {
    assert(si(v) > 1);
    set<P> S;
    sort(all(v), [](P a, P b) { return a.y < b.y; });
    pair<ld, pair<P, P>> ret{LLONG_MAX, {P(), P()}};
    int j = 0;
    fore(p, v) {
        P d{1 + (ld)sqrt(ret.first), 0};
        while (v[j].y <= p.y - d.x) S.erase(v[j++]);
        auto lo = S.lower_bound(p - d), hi = S.upper_bound(p + d);
        for (; lo != hi; ++lo) ret = min(ret, {(*lo - p).dist2(), {*lo, p}});
        S.insert(p);
    }
    return ret.second;
} 

using P = Point<long double>;

int main() {
    int n;
    cin >> n;
    vector<P> v;
    rep(i, n) {
        double x, y;
        cin >> x >> y;
        v.push_back(P(x, y));
    }

    cout << setprecision(20);
    auto res = closest(v);
    cout << (res.first - res.second).dist() << endl;;
}
accuracy: 0.40625
time_ms: 780
memory_kb: 4844
final_rank: 20

code_snippet: #include<bits/stdc++.h>
using namespace std;
int n;
vector<pair<double,double>> point;
double distance(pair<double,double> a, pair<double,double> b)
{
    return sqrt((a.first-b.first)*(a.first-b.first)
    +(a.second-b.second)*(a.second-b.second));
}
double bruteforce(int left, int right)
{
    double mind=INT_MAX;
    for(int i=left;i<right;i++)
        mind=min(mind,distance(point[i],point[i+1]));
    return mind;
}
double recursion(int left, int right)
{
    if(right-left+1<=3)
    {
        return bruteforce(left,right);
    }
    int midx=left+(right-left+1)/2;
    double d=min(recursion(left,midx),recursion(midx+1,right));
    vector<pair<double,double>> strip;
    for(int i=left;i<=midx;i++)
    {
        if(abs(point[i].first-point[midx].first)<d)
            strip.push_back({point[i].second,point[i].first});
    }
    for(int i=midx+1;i<=right;i++)
    {
        if(abs(point[i].first-point[midx].first)<d)
            strip.push_back({point[i].second,point[i].first});
    }
    sort(strip.begin(),strip.end());
    for(int i=0;i<strip.size();i++)
    {
        for(int j=i+1;j<min(i+8,(int)strip.size());j++)
        d=min(d,distance(strip[i],strip[j]));
    }
    return d;
}
int main()
{

    cin>>n;
    for(int i=0;i<n;i++)
    {
        double a,b;
        cin>>a>>b;
        point.push_back({a,b});
    }
    sort(point.begin(),point.end());
    cout << fixed << setprecision(12) << recursion(0,n-1);
}
accuracy: 1
time_ms: 90
memory_kb: 7632
final_rank: 6

code_snippet: // --- Start of include: ./../../akakoi_lib/template/template.cpp ---
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3,unroll-loops")
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i,n) for(ll i=0;i<(ll)(n);++i)
bool chmin(auto& a, auto b) {return a>b?a=b,1:0;}
bool chmax(auto& a, auto b) {return a<b?a=b,1:0;}
// int main() {
//     ios::sync_with_stdio(false);
//     cin.tie(0);
// }
// --- End of include: ./../../akakoi_lib/template/template.cpp ---
// --- Start of include: ./../../akakoi_lib/geometry/geometry.cpp ---
/// @brief 幾何ライブラリ
namespace Geometry {
 using Real = long double;
 const Real EPS = 1e-9;

 bool almostEqual(Real a, Real b) { return abs(a - b) < EPS; }
 bool lessThan(Real a, Real b) { return a < b && !almostEqual(a, b); }
 bool greaterThan(Real a, Real b) { return a > b && !almostEqual(a, b); }
 bool lessThanOrEqual(Real a, Real b) { return a < b || almostEqual(a, b); }
 bool greaterThanOrEqual(Real a, Real b) { return a > b || almostEqual(a, b); }

 /// @brief ２次元平面上の位置ベクトル
 struct Point {
  Real x, y;
  Point() = default;
  Point(Real x, Real y) : x(x), y(y) {}

  Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
  Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
  Point operator*(Real k) const { return Point(x * k, y * k); }
  Point operator/(Real k) const { return Point(x / k, y / k); }

  /// @brief p との内積を返す
  Real dot(const Point& p) const { return x * p.x + y * p.y; }

  /// @brief p との外積を返す
  Real cross(const Point& p) const { return x * p.y - y * p.x; }

  /// @brief p1 と p2 を端点とするベクトルとの外積を返す
  Real cross(const Point& p1, const Point& p2) const { return (p1.x - x) * (p2.y - y) - (p1.y - y) * (p2.x - x); }

  /// @brief ２乗ノルムを返す
  Real norm() const { return x * x + y * y; }

  /// @brief ユークリッドノルムを返す
  Real abs() const { return sqrt(norm()); }

  /// @brief 偏角を返す
  Real arg() const { return atan2(y, x); }

  bool operator==(const Point& p) const { return almostEqual(x, p.x) && almostEqual(y, p.y); }
  friend istream& operator>>(istream& is, Point& p) { return is >> p.x >> p.y; }
 };

 /// @brief 直線
 struct Line {
  Point a, b;
  Line() = default;
  Line(const Point& _a, const Point& _b) : a(_a), b(_b) {}

  /// @brief 直線 Ax+By=C を定義する
  Line(const Real& A, const Real& B, const Real& C) {
   if (almostEqual(A, 0)) {
    assert(!almostEqual(B, 0));
    a = Point(0, C / B);
    b = Point(1, C / B);
   } else if (almostEqual(B, 0)) {
    a = Point(C / A, 0);
    b = Point(C / A, 1);
   } else if (almostEqual(C, 0)) {
    a = Point(0, C / B);
    b = Point(1, (C - A) / B);
   } else {
    a = Point(0, C / B);
    b = Point(C / A, 0);
   }
  }

  bool operator==(const Line& l) const { return a == l.a && b == l.b; }
  friend istream& operator>>(istream& is, Line& l) { return is >> l.a >> l.b; }
 };

 /// @brief 線分
 struct Segment : Line {
  Segment() = default;
  using Line::Line;
 };

 /// @brief 円
 struct Circle {
  Point center;  ///< 中心
  Real r;  ///< 半径

  Circle() = default;
  Circle(Real x, Real y, Real r) : center(x, y), r(r) {}
  Circle(Point _center, Real r) : center(_center), r(r) {}

  bool operator==(const Circle& C) const { return center == C.center && r == C.r; }
  friend istream& operator>>(istream& is, Circle& C) { return is >> C.center >> C.r; }
 };

 //-----------------------------------------------------------

 /// @brief 3点の進行方向
 enum Orientation {
  COUNTER_CLOCKWISE,  ///< 反時計回り
  CLOCKWISE,  ///< 時計回り
  ONLINE_BACK,
  ONLINE_FRONT,
  ON_SEGMENT
 };

 /// @brief 3点 p0, p1, p2 の進行方向を返す
 Orientation ccw(const Point& p0, const Point& p1, const Point& p2) {
  Point a = p1 - p0;
  Point b = p2 - p0;
  Real cross_product = a.cross(b);
  if (greaterThan(cross_product, 0)) return COUNTER_CLOCKWISE;
  if (lessThan(cross_product, 0)) return CLOCKWISE;
  if (lessThan(a.dot(b), 0)) return ONLINE_BACK;
  if (lessThan(a.norm(), b.norm())) return ONLINE_FRONT;
  return ON_SEGMENT;
 }

 string orientationToString(Orientation o) {
  switch (o) {
   case COUNTER_CLOCKWISE:
    return "COUNTER_CLOCKWISE";
   case CLOCKWISE:
    return "CLOCKWISE";
   case ONLINE_BACK:
    return "ONLINE_BACK";
   case ONLINE_FRONT:
    return "ONLINE_FRONT";
   case ON_SEGMENT:
    return "ON_SEGMENT";
   default:
    return "UNKNOWN";
  }
 }

 /// @brief ベクトル p の直線 p1, p2 への正射影ベクトルを返す
 Point projection(const Point& p1, const Point& p2, const Point& p) {
  Point base = p2 - p1;
  Real r = (p - p1).dot(base) / base.norm();
  return p1 + base * r;
 }

 /// @brief ベクトル p の直線 l への正射影ベクトルを返す
 Point projection(const Line& l, const Point& p) {
  Point base = l.b - l.a;
  Real r = (p - l.a).dot(base) / base.norm();
  return l.a + base * r;
 }

 /// @brief ベクトル p の直線 p1, p2 に対する鏡像ベクトルを返す
 Point reflection(const Point& p1, const Point& p2, const Point& p) {
  Point proj = projection(p1, p2, p);
  return proj * 2 - p;
 }

 /// @brief ベクトル p の直線 l に対する鏡像ベクトルを返す
 Point reflection(const Line& l, const Point& p) {
  Point proj = projection(l, p);
  return proj * 2 - p;
 }

 //-----------------------------------------------------------

 /// @brief 直線の平行判定
 bool isParallel(const Line& l1, const Line& l2) { return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0); }
 /// @brief 直線の直交判定
 bool isOrthogonal(const Line& l1, const Line& l2) { return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0); }
 /// @brief 線分の平行判定
 bool isParallel(const Segment& l1, const Segment& l2) { return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0); }
 /// @brief 線分の直交判定
 bool isOrthogonal(const Segment& l1, const Segment& l2) { return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0); }
 /// @brief 直線と線分の平行判定
 bool isParallel(const Line& l1, const Segment& l2) { return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0); }
 /// @brief 直線と線分の直交判定
 bool isOrthogonal(const Line& l1, const Segment& l2) { return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0); }
 /// @brief 線分と直線の平行判定
 bool isParallel(const Segment& l1, const Line& l2) { return almostEqual((l1.b - l1.a).cross(l2.b - l2.a), 0); }
 /// @brief 線分と直線の直交判定
 bool isOrthogonal(const Segment& l1, const Line& l2) { return almostEqual((l1.b - l1.a).dot(l2.b - l2.a), 0); }
 /// @brief 点が直線上にあるか判定
 bool isPointOnLine(const Point& p, const Line& l) { return almostEqual((l.b - l.a).cross(p - l.a), 0.0); }

 /// @brief 点が線分上にあるか判定
 bool isPointOnSegment(const Point& p, const Segment& s) {
  return lessThanOrEqual(min(s.a.x, s.b.x), p.x) &&
     lessThanOrEqual(p.x, max(s.a.x, s.b.x)) &&
     lessThanOrEqual(min(s.a.y, s.b.y), p.y) &&
     lessThanOrEqual(p.y, max(s.a.y, s.b.y)) &&
     almostEqual((s.b - s.a).cross(p - s.a), 0.0);
 }

 /// @brief 直線の交差判定
 bool isIntersecting(const Segment& s1, const Segment& s2) {
  Point p0p1 = s1.b - s1.a, p0p2 = s2.a - s1.a, p0p3 = s2.b - s1.a, p2p3 = s2.b - s2.a, p2p0 = s1.a - s2.a, p2p1 = s1.b - s2.a;
  Real d1 = p0p1.cross(p0p2), d2 = p0p1.cross(p0p3), d3 = p2p3.cross(p2p0), d4 = p2p3.cross(p2p1);
  if (lessThan(d1 * d2, 0) && lessThan(d3 * d4, 0)) return true;
  if (almostEqual(d1, 0.0) && isPointOnSegment(s2.a, s1)) return true;
  if (almostEqual(d2, 0.0) && isPointOnSegment(s2.b, s1)) return true;
  if (almostEqual(d3, 0.0) && isPointOnSegment(s1.a, s2)) return true;
  if (almostEqual(d4, 0.0) && isPointOnSegment(s1.b, s2)) return true;
  return false;
 }

 /// @brief 線分の交点を返す
 Point getIntersection(const Segment& s1, const Segment& s2) {
  assert(isIntersecting(s1, s2));
  auto cross = [](Point p, Point q) { return p.x * q.y - p.y * q.x; };
  Point base = s2.b - s2.a;
  Real d1 = abs(cross(base, s1.a - s2.a));
  Real d2 = abs(cross(base, s1.b - s2.a));
  Real t = d1 / (d1 + d2);
  return s1.a + (s1.b - s1.a) * t;
 }

 /// @brief 点と線分の距離を返す
 Real distancePointToSegment(const Point& p, const Segment& s) {
  Point proj = projection(s.a, s.b, p);
  if (isPointOnSegment(proj, s))
   return (p - proj).abs();
  else
   return min((p - s.a).abs(), (p - s.b).abs());
 }

 /// @brief 線分と線分の距離を返す
 Real distanceSegmentToSegment(const Segment& s1, const Segment& s2) {
  if (isIntersecting(s1, s2)) return 0.0;
  return min({distancePointToSegment(s1.a, s2),
     distancePointToSegment(s1.b, s2),
     distancePointToSegment(s2.a, s1),
     distancePointToSegment(s2.b, s1)});
 }

 //-----------------------------------------------------------

 /// @brief 多角形の面積を返す
 Real getPolygonArea(const vector<Point>& points) {
  int n = points.size();
  Real area = 0.0;
  for (int i = 0; i < n; i++) {
   int j = (i + 1) % n;
   area += points[i].x * points[j].y;
   area -= points[i].y * points[j].x;
  }
  return abs(area) / 2.0;
 }

 /// @brief 多角形が凸か判定
 bool isConvex(const vector<Point>& points) {
  int n = points.size();
  bool has_positive = false, has_negative = false;
  for (int i = 0; i < n; i++) {
   int j = (i + 1) % n;
   int k = (i + 2) % n;
   Point a = points[j] - points[i];
   Point b = points[k] - points[j];
   Real cross_product = a.cross(b);
   if (greaterThan(cross_product, 0)) has_positive = true;
   if (lessThan(cross_product, 0)) has_negative = true;
  }
  return !(has_positive && has_negative);
 }

 /// @brief 点が凸多角形の辺上に存在するか判定
 bool isPointOnPolygon(const vector<Point>& polygon, const Point& p) {
  int n = polygon.size();
  for (int i = 0; i < n; i++) {
   Point a = polygon[i];
   Point b = polygon[(i + 1) % n];
   Segment s(a, b);
   if (isPointOnSegment(p, s)) return true;
  }
  return false;
 }

 /// @brief 点が多角形の内部に存在するか判定（辺上は含まない）
 bool isPointInsidePolygon(const vector<Point>& polygon, const Point& p) {
  int n = polygon.size();
  bool inPolygon = false;
  for (int i = 0; i < n; i++) {
   Point a = polygon[i];
   Point b = polygon[(i + 1) % n];
   if (greaterThan(a.y, b.y)) swap(a, b);
   if (lessThanOrEqual(a.y, p.y) && lessThan(p.y, b.y) && greaterThan((b - a).cross(p - a), 0)) inPolygon = !inPolygon;
  }
  return inPolygon;
 }

 //-----------------------------------------------------------

 /// @brief 凸包を求める
 vector<Point> convexHull(vector<Point>& points, bool include_collinear = false) {
  int n = points.size();
  if (n <= 1) return points;
  sort(points.begin(), points.end(), [](const Point& l, const Point& r) -> bool {
   if (almostEqual(l.y, r.y)) return lessThan(l.x, r.x);
   return lessThan(l.y, r.y);
  });
  if (n == 2) return points;
  vector<Point> upper = {points[0], points[1]}, lower = {points[0], points[1]};
  for (int i = 2; i < n; i++) {
   while (upper.size() >= 2 && ccw(upper.end()[-2], upper.end()[-1], points[i]) != CLOCKWISE) {
    if (ccw(upper.end()[-2], upper.end()[-1], points[i]) == ONLINE_FRONT && include_collinear) break;
    upper.pop_back();
   }
   upper.push_back(points[i]);
   while (lower.size() >= 2 && ccw(lower.end()[-2], lower.end()[-1], points[i]) != COUNTER_CLOCKWISE) {
    if (ccw(lower.end()[-2], lower.end()[-1], points[i]) == ONLINE_FRONT && include_collinear) break;
    lower.pop_back();
   }
   lower.push_back(points[i]);
  }
  reverse(upper.begin(), upper.end());
  upper.pop_back();
  lower.pop_back();
  lower.insert(lower.end(), upper.begin(), upper.end());
  return lower;
 }

 /// @brief 凸包の直径を求める
 Real convexHullDiameter(const vector<Point>& hull) {
  int n = hull.size();
  if (n == 1) return 0;
  int k = 1;
  Real max_dist = 0;
  for (int i = 0; i < n; i++) {
   while (true) {
    int j = (k + 1) % n;
    Point dist1 = hull[i] - hull[j], dist2 = hull[i] - hull[k];
    max_dist = max(max_dist, dist1.abs());
    max_dist = max(max_dist, dist2.abs());
    if (dist1.abs() > dist2.abs())
     k = j;
    else
     break;
   }
   Point dist = hull[i] - hull[k];
   max_dist = max(max_dist, dist.abs());
  }
  return max_dist;
 }

 /// @brief 凸包を直線で切断して左側を返す
 vector<Point> cutPolygon(const vector<Point>& g, const Line& l) {
  auto isLeft = [](const Point& p1, const Point& p2, const Point& p) -> bool { return (p2 - p1).cross(p - p1) > 0; };
  vector<Point> newPolygon;
  int n = g.size();
  for (int i = 0; i < n; i++) {
   const Point& cur = g[i];
   const Point& next = g[(i + 1) % n];
   if (isLeft(l.a, l.b, cur)) newPolygon.push_back(cur);
   if ((isLeft(l.a, l.b, cur) && !isLeft(l.a, l.b, next)) || (!isLeft(l.a, l.b, cur) && isLeft(l.a, l.b, next))) {
    Real A1 = (next - cur).cross(l.a - cur);
    Real A2 = (next - cur).cross(l.b - cur);
    Point intersection = l.a + (l.b - l.a) * (A1 / (A1 - A2));
    newPolygon.push_back(intersection);
   }
  }
  return newPolygon;
 }

 //-----------------------------------------------------------

 /// @brief 最近点対の距離を求める
 /// @note points は x 座標でソートされている必要がある
 Real closestPair(vector<Point>& points, int l, int r) {
  if (r - l <= 1) return numeric_limits<Real>::max();
  int mid = (l + r) >> 1;
  Real x = points[mid].x;
  Real d = min(closestPair(points, l, mid), closestPair(points, mid, r));
  auto iti = points.begin(), itl = iti + l, itm = iti + mid, itr = iti + r;
  inplace_merge(itl, itm, itr, [](const Point& lhs, const Point& rhs) -> bool {
   return lessThan(lhs.y, rhs.y);
  });
  vector<Point> nearLine;
  for (int i = l; i < r; i++) {
   if (greaterThanOrEqual(fabs(points[i].x - x), d)) continue;
   int sz = nearLine.size();
   for (int j = sz - 1; j >= 0; j--) {
    Point dv = points[i] - nearLine[j];
    if (dv.y >= d) break;
    d = min(d, dv.abs());
   }
   nearLine.push_back(points[i]);
  }
  return d;
 }

 //-----------------------------------------------------------

 /// @brief 線分の交差数を数える
 int countIntersections(vector<Segment> segments) {
  struct Event {
   Real x;
   int type;  // 0:horizontal start,1:vertical,2:horizontal end
   Real y1, y2;
   Event(Real x, int type, Real y1, Real y2) : x(x), type(type), y1(y1), y2(y2) {}
   bool operator<(const Event& other) const {
    if (x == other.x) return type < other.type;
    return x < other.x;
   }
  };
  vector<Event> events;
  sort(segments.begin(), segments.end(), [](const Segment& lhs, const Segment& rhs) -> bool {
   return lessThan(min(lhs.a.x, lhs.b.x), min(rhs.a.x, rhs.b.x));
  });
  for (const auto& seg : segments) {
   if (seg.a.y == seg.b.y) {
    // Horizontal segment
    Real y = seg.a.y;
    Real x1 = min(seg.a.x, seg.b.x);
    Real x2 = max(seg.a.x, seg.b.x);
    events.emplace_back(x1, 0, y, y);
    events.emplace_back(x2, 2, y, y);
   } else {
    // Vertical segment
    Real x = seg.a.x;
    Real y1 = min(seg.a.y, seg.b.y);
    Real y2 = max(seg.a.y, seg.b.y);
    events.emplace_back(x, 1, y1, y2);
   }
  }
  sort(events.begin(), events.end());
  set<Real> activeSegments;
  int intersectionCount = 0;
  for (const auto& event : events) {
   if (event.type == 0) {
    // Add horizontal segment to active set
    activeSegments.insert(event.y1);
   } else if (event.type == 2) {
    // Remove horizontal segment from active set
    activeSegments.erase(event.y1);
   } else if (event.type == 1) {
    // Count intersections with vertical segment
    auto lower = activeSegments.lower_bound(event.y1);
    auto upper = activeSegments.upper_bound(event.y2);
    intersectionCount += distance(lower, upper);
   }
  }
  return intersectionCount;
 }

 //-----------------------------------------------------------

 /// @brief 2つの円の交点の個数を返す
 int countCirclesIntersection(const Circle& c1, const Circle& c2) {
  Real d =
   sqrt((c1.center.x - c2.center.x) * (c1.center.x - c2.center.x) +
     (c1.center.y - c2.center.y) * (c1.center.y - c2.center.y));
  Real r1 = c1.r, r2 = c2.r;
  if (greaterThan(d, r1 + r2))
   return 4;
  else if (almostEqual(d, r1 + r2))
   return 3;
  else if (greaterThan(d, fabs(r1 - r2)))
   return 2;
  else if (almostEqual(d, fabs(r1 - r2)))
   return 1;
  else
   return 0;
 }

 /// @brief 内接円を求める
 Circle getInCircle(const Point& A, const Point& B, const Point& C) {
  Real a = (B - C).abs();
  Real b = (A - C).abs();
  Real c = (A - B).abs();
  Real s = (a + b + c) / 2;
  Real area = sqrt(s * (s - a) * (s - b) * (s - c));
  Real r = area / s;
  Real cx = (a * A.x + b * B.x + c * C.x) / (a + b + c);
  Real cy = (a * A.y + b * B.y + c * C.y) / (a + b + c);
  return Circle{Point(cx, cy), r};
 }

 /// @brief 外接円を求める
 Circle getCircumCircle(const Point& A, const Point& B, const Point& C) {
  Real D = 2 * (A.x * (B.y - C.y) + B.x * (C.y - A.y) + C.x * (A.y - B.y));
  Real Ux = ((A.x * A.x + A.y * A.y) * (B.y - C.y) + (B.x * B.x + B.y * B.y) * (C.y - A.y) + (C.x * C.x + C.y * C.y) * (A.y - B.y)) / D;
  Real Uy = ((A.x * A.x + A.y * A.y) * (C.x - B.x) + (B.x * B.x + B.y * B.y) * (A.x - C.x) + (C.x * C.x + C.y * C.y) * (B.x - A.x)) / D;
  Point center(Ux, Uy);
  Real radius = (center - A).abs();
  return Circle{center, radius};
 }

 /// @brief 円と直線の交点を求める
 vector<Point> getCircleLineIntersection(const Circle& c, Point p1, Point p2) {
  Real cx = c.center.x, cy = c.center.y, r = c.r;
  Real dx = p2.x - p1.x;
  Real dy = p2.y - p1.y;
  Real a = dx * dx + dy * dy;
  Real b = 2 * (dx * (p1.x - cx) + dy * (p1.y - cy));
  Real c_const = (p1.x - cx) * (p1.x - cx) + (p1.y - cy) * (p1.y - cy) - r * r;
  Real discriminant = b * b - 4 * a * c_const;
  vector<Point> intersections;
  if (almostEqual(discriminant, 0)) {
   Real t = -b / (2 * a);
   Real ix = p1.x + t * dx;
   Real iy = p1.y + t * dy;
   intersections.emplace_back(ix, iy);
   intersections.emplace_back(ix, iy);
  } else if (discriminant > 0) {
   Real sqrt_discriminant = sqrt(discriminant);
   Real t1 = (-b + sqrt_discriminant) / (2 * a);
   Real t2 = (-b - sqrt_discriminant) / (2 * a);
   Real ix1 = p1.x + t1 * dx;
   Real iy1 = p1.y + t1 * dy;
   Real ix2 = p1.x + t2 * dx;
   Real iy2 = p1.y + t2 * dy;
   intersections.emplace_back(ix1, iy1);
   intersections.emplace_back(ix2, iy2);
  }
  if (almostEqual(intersections[0].x, intersections[1].x)) {
   if (greaterThan(intersections[0].y, intersections[1].y)) swap(intersections[0], intersections[1]);
  } else if (greaterThan(intersections[0].x, intersections[1].x)) {
   swap(intersections[0], intersections[1]);
  }
  return intersections;
 }

 /// @brief 2つの円の交点を求める
 vector<Point> getCirclesIntersect(const Circle& c1, const Circle& c2) {
  Real x1 = c1.center.x, y1 = c1.center.y, r1 = c1.r;
  Real x2 = c2.center.x, y2 = c2.center.y, r2 = c2.r;
  Real d = sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
  if (d > r1 + r2 || d < abs(r1 - r2)) return {};  // No intersection
  Real a = (r1 * r1 - r2 * r2 + d * d) / (2 * d);
  Real h = sqrt(r1 * r1 - a * a);
  Real x0 = x1 + a * (x2 - x1) / d;
  Real y0 = y1 + a * (y2 - y1) / d;
  Real rx = -(y2 - y1) * (h / d);
  Real ry = (x2 - x1) * (h / d);
  Point p1(x0 + rx, y0 + ry);
  Point p2(x0 - rx, y0 - ry);
  vector<Point> intersections;
  intersections.push_back(p1);
  intersections.push_back(p2);
  if (almostEqual(intersections[0].x, intersections[1].x)) {
   if (greaterThan(intersections[0].y, intersections[1].y)) swap(intersections[0], intersections[1]);
  } else if (greaterThan(intersections[0].x, intersections[1].x)) {
   swap(intersections[0], intersections[1]);
  }
  return intersections;
 }

 /// @brief 点から引ける円の接線の接点を求める
 vector<Point> getTangentLinesFromPoint(const Circle& c, const Point& p) {
  Real cx = c.center.x, cy = c.center.y, r = c.r;
  Real px = p.x, py = p.y;
  Real dx = px - cx;
  Real dy = py - cy;
  Real d = (p - c.center).abs();
  if (lessThan(d, r))
   return {};  // No tangents if the point is inside the circle
  else if (almostEqual(d, r))
   return {p};
  Real a = r * r / d;
  Real h = sqrt(r * r - a * a);
  Real cx1 = cx + a * dx / d;
  Real cy1 = cy + a * dy / d;
  vector<Point> tangents;
  tangents.emplace_back(cx1 + h * dy / d, cy1 - h * dx / d);
  tangents.emplace_back(cx1 - h * dy / d, cy1 + h * dx / d);
  if (almostEqual(tangents[0].x, tangents[1].x)) {
   if (greaterThan(tangents[0].y, tangents[1].y)) swap(tangents[0], tangents[1]);
  } else if (greaterThan(tangents[0].x, tangents[1].x)) {
   swap(tangents[0], tangents[1]);
  }
  return tangents;
 }

 /// @brief 2つの円の共通接線を求める
 vector<Segment> getCommonTangentsLine(const Circle& c1, const Circle& c2) {
  Real x1 = c1.center.x, y1 = c1.center.y, r1 = c1.r;
  Real x2 = c2.center.x, y2 = c2.center.y, r2 = c2.r;
  Real dx = x2 - x1;
  Real dy = y2 - y1;
  Real d = sqrt(dx * dx + dy * dy);
  vector<Segment> tangents;
  // Coincident circles(infinite tangents)
  if (almostEqual(d, 0) && almostEqual(r1, r2)) return tangents;
  // External tangents
  if (greaterThanOrEqual(d, r1 + r2)) {
   Real a = atan2(dy, dx);
   for (int sign : {-1, 1}) {
    Real theta = acos((r1 + r2) / d);
    Real cx1 = x1 + r1 * cos(a + sign * theta);
    Real cy1 = y1 + r1 * sin(a + sign * theta);
    Real cx2 = x2 + r2 * cos(a + sign * theta);
    Real cy2 = y2 + r2 * sin(a + sign * theta);
    tangents.emplace_back(Segment{Point(cx1, cy1), Point(cx2, cy2)});
    if (almostEqual(d, r1 + r2)) break;
   }
  }
  // Internal tangents
  if (greaterThanOrEqual(d, fabs(r1 - r2))) {
   Real a = atan2(dy, dx);
   for (int sign : {-1, 1}) {
    Real theta = acos((r1 - r2) / d);
    Real cx1 = x1 + r1 * cos(a + sign * theta);
    Real cy1 = y1 + r1 * sin(a + sign * theta);
    Real cx2 = x2 - r2 * cos(a + sign * theta);
    Real cy2 = y2 - r2 * sin(a + sign * theta);
    tangents.emplace_back(Segment{Point(cx1, cy1), Point(cx2, cy2)});
    if (almostEqual(d, fabs(r1 - r2))) break;
   }
  }
  sort(tangents.begin(), tangents.end(), [&](const Segment& s1, const Segment& s2) {
   if (almostEqual(s1.a.x, s2.a.x))
    return lessThan(s1.a.y, s2.a.y);
   else
    return lessThan(s1.a.x, s2.a.x);
  });
  return tangents;
 }
}
// --- End of include: ./../../akakoi_lib/geometry/geometry.cpp ---

using namespace Geometry;

void solve() {
  int n; cin >> n;
  vector<Point> P(n);
  rep(i, n) {
    Real x, y; cin >> x >> y;
    P[i] = {x, y};
  }
  sort(P.begin(), P.end(), [&] (Point &l, Point &r) {
    return l.x < r.x;
  });
  cout << closestPair(P, 0, P.size()) << endl;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(10);
  solve();
  return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 13424
final_rank: 15

code_snippet: // https://tubo28.me/compprog/algorithm/ より.

#include <bits/stdc++.h>
// #define int int64_t

#define FOR(i, a, b) for (int i = (a); i < int(b); ++i)
#define RFOR(i, a, b) for (int i = (b)-1; i >= int(a); --i)
#define rep(i, n) FOR(i, 0, n)
#define rep1(i, n) FOR(i, 1, int(n) + 1)
#define rrep(i, n) RFOR(i, 0, n)
#define rrep1(i, n) RFOR(i, 1, int(n) + 1)
#define all(c) begin(c), end(c)
namespace io {
#ifdef LOCAL
#define dump(...)                                         \
    do {                                                  \
        std::ostringstream os;                            \
        os << __LINE__ << ":\t" << #__VA_ARGS__ << " = "; \
        io::print_to(os, ", ", "\n", __VA_ARGS__);        \
        std::cerr << io::highlight(os.str());             \
    } while (0)
#define dump_(cntnr)                                 \
    do {                                             \
        std::ostringstream os;                       \
        os << __LINE__ << ":\t" << #cntnr << " = ["; \
        io::print_to_(os, ", ", "]\n", all(cntnr));  \
        std::cerr << io::highlight(os.str());        \
    } while (0)
#define dumpf(fmt, ...)                             \
    do {                                            \
        const int N = 4096;                         \
        auto b = new char[N];                       \
        int l = snprintf(b, N, "%d:\t", __LINE__);  \
        snprintf(b + l, N - l, fmt, ##__VA_ARGS__); \
        std::cerr << io::highlight(b) << std::endl; \
        delete[] b;                                 \
    } while (0)
#else
#define dump(...)
#define dump_(...)
#define dumpf(...)
#endif
std::string highlight(std::string s) {
#ifdef _MSC_VER
    return s;
#else
    return "\033[33m" + s + "\033[0m";
#endif
}
template <typename T>
void print_to(std::ostream &os, std::string, std::string tail, const T &first) {
    os << first << tail;
}
template <typename F, typename... R>
void print_to(std::ostream &os, std::string del, std::string tail, const F &first,
              const R &... rest) {
    os << first << del;
    print_to(os, del, tail, rest...);
}
template <typename I>
void print_to_(std::ostream &os, std::string del, std::string tail, I begin, I end) {
    for (I it = begin; it != end;) {
        os << *it;
        os << (++it != end ? del : tail);
    }
}
template <typename F, typename... R>
void println(const F &first, const R &... rest) {
    print_to(std::cout, "\n", "\n", first, rest...);
}
template <typename F, typename... R>
void print(const F &first, const R &... rest) {
    print_to(std::cout, " ", "\n", first, rest...);
}
template <typename I>
void println_(I begin, I end) {
    print_to_(std::cout, "\n", "\n", begin, end);
}
template <typename I>
void print_(I begin, I end) {
    print_to_(std::cout, " ", "\n", begin, end);
}
template <typename C>
void println_(const C &cntnr) {
    println_(std::begin(cntnr), std::end(cntnr));
}
template <typename C>
void print_(const C &cntnr) {
    print_(std::begin(cntnr), std::end(cntnr));
}
int _ = (
#ifndef LOCAL
    std::cin.tie(nullptr), std::ios::sync_with_stdio(false),
#endif
    std::cout.precision(10), std::cout.setf(std::ios::fixed));
}
using io::print;
using io::println;
using io::println_;
using io::print_;
template <typename T>
using vec = std::vector<T>;
using vi = vec<int>;
using vvi = vec<vi>;
using pii = std::pair<int, int>;
using ll = long long;
using ld = long double;
using namespace std;
// const int MOD = 1000000007;




using ld = long double;
using P = std::complex<ld>;
using G = std::vector<P>;
const ld pi = std::acos(-1);
const ld eps = 1e-10;
const ld inf = 1e12;

ld cross(const P &a, const P &b) { return a.real() * b.imag() - a.imag() * b.real(); }
ld dot(const P &a, const P &b) { return a.real() * b.real() + a.imag() * b.imag(); }

/*
                    CCW

 -- BEHIND -- [a -- ON -- b] --- FRONT --

                    CW
 */
enum CCW_RESULT { CCW = +1, CW = -1, BEHIND = +2, FRONT = -2, ON = 0 };
int ccw(P a, P b, P c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps) return CCW;    // counter clockwise
    if (cross(b, c) < -eps) return CW;    // clockwise
    if (dot(b, c) < 0) return BEHIND;     // c--a--b on line
    if (norm(b) < norm(c)) return FRONT;  // a--b--c on line
    return ON;
}

namespace std {
bool operator<(const P &a, const P &b) {
    return std::abs(real(a) - real(b)) > eps ? real(a) < real(b) : imag(a) < imag(b);
}
}

struct L : public std::vector<P> {
    L(const P &a = P(), const P &b = P()) : std::vector<P>(2) {
        begin()[0] = a;
        begin()[1] = b;
    }

    // Ax + By + C = 0
    L(ld A, ld B, ld C) {
        if (std::abs(A) < eps && std::abs(B) < eps) {
            abort();
        } else if (std::abs(A) < eps) {
            *this = L(P(0, -C / B), P(1, -C / B));
        } else if (std::abs(B) < eps) {
            *this = L(P(-C / A, 0), P(-C / A, 1));
        } else {
            *this = L(P(0, -C / B), P(-C / A, 0));
        }
    }
};

struct C {
    P p;
    ld r;
    C(const P &p = 0, ld r = 0) : p(p), r(r) {}
};




bool intersectLL(const L &l, const L &m) {
    return std::abs(cross(l[1] - l[0], m[1] - m[0])) > eps ||  // non-parallel
           std::abs(cross(l[1] - l[0], m[0] - l[0])) < eps;    // same line
}
bool intersectLS(const L &l, const L &s) {
    return cross(l[1] - l[0], s[0] - l[0]) *  // s[0] is left of l
               cross(l[1] - l[0], s[1] - l[0]) <
           eps;  // s[1] is right of l
}
bool intersectLP(const L &l, const P &p) { return std::abs(cross(l[1] - p, l[0] - p)) < eps; }
bool intersectSS(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 intersectSP(const L &s, const P &p) {
    return std::abs(s[0] - p) + std::abs(s[1] - p) - std::abs(s[1] - s[0]) <
           eps;  // triangle inequality
}

P projection(const L &l, const P &p) {
    ld t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
    return l[0] + t * (l[0] - l[1]);
}
P reflection(const L &l, const P &p) { return p + (ld)2 * (projection(l, p) - p); }
ld distanceLP(const L &l, const P &p) { return std::abs(p - projection(l, p)); }
ld distanceLL(const L &l, const L &m) { return intersectLL(l, m) ? 0 : distanceLP(l, m[0]); }
ld distanceLS(const L &l, const L &s) {
    if (intersectLS(l, s)) return 0;
    return std::min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
ld distanceSP(const L &s, const P &p) {
    const P r = projection(s, p);
    if (intersectSP(s, r)) return std::abs(r - p);
    return std::min(std::abs(s[0] - p), std::abs(s[1] - p));
}
ld distanceSS(const L &s, const L &t) {
    if (intersectSS(s, t)) return 0;
    return std::min(std::min(distanceSP(s, t[0]), distanceSP(s, t[1])),
                    std::min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
P crosspointLL(const L &l, const L &m) {
    ld A = cross(l[1] - l[0], m[1] - m[0]);
    ld B = cross(l[1] - l[0], l[1] - m[0]);
    if (std::abs(A) < eps && std::abs(B) < eps) return m[0];  // same line
    if (std::abs(A) < eps) assert(false);                     // !!!PRECONDITION NOT SATISFIED!!!
    return m[0] + B / A * (m[1] - m[0]);
}


// 符号付二倍面積 abs(area2(G pol))/2.0 で求められる.
// polは頂点反時計回りで渡す
ld area2(const G& pol) {
    ld s = 0;
    int n = pol.size();
    for (int i = 0; i < n; ++i) s += cross(pol[i], pol[(i + 1) % n]);
    return s;
}


// 凸包
// == CWを != CCWに置換すると 退化した角を除く.
G andrewScan(G ps) {
    int N = ps.size(), k = 0;
    std::sort(ps.begin(), ps.end());
    G res(N * 2);
    for (int i = 0; i < N; i++) {
        while (k >= 2 && ccw(res[k - 2], res[k - 1], ps[i]) == CW) k--;
        res[k++] = ps[i];
    }
    int t = k + 1;
    for (int i = N - 2; i >= 0; i--) {
        while (k >= t && ccw(res[k - 2], res[k - 1], ps[i]) == CW) k--;
        res[k++] = ps[i];
    }
    res.resize(k - 1);
    return res;
}
//凸包終.

/*
// 凸多角形の直径
// 最近点対と競合.
#define curr(P, i) P[i]
#define next(P, i) P[(i + 1) % P.size()]
#define diff(P, i) (next(P, i) - curr(P, i))
ld convex_diameter(const G &pt) {
    const int n = pt.size();
    int is = 0, js = 0;
    for (int i = 1; i < n; ++i) {
        if (imag(pt[i]) > imag(pt[is])) is = i;
        if (imag(pt[i]) < imag(pt[js])) js = i;
    }
    ld maxd = norm(pt[is] - pt[js]);
    int i, maxi, j, maxj;
    i = maxi = is;
    j = maxj = js;
    do {
        if (cross(diff(pt, i), diff(pt, j)) >= 0)
            j = (j + 1) % n;
        else
            i = (i + 1) % n;
        if (norm(pt[i] - pt[j]) > maxd) {
            maxd = norm(pt[i] - pt[j]);
            maxi = i;
            maxj = j;
        }
    } while (i != is || j != js);
    return maxd; /* farthest pair is (maxi, maxj). */
/*
}
*/

//凸多角形の直径終.

// 凸多角形の切断. (左側のみ)
// 右側: lを逆に.
//@require intersection.cc
G convex_cut(const G& pol, const L& l) {
    G res;
    int n = pol.size();
    for (int i = 0; i < n; ++i) {
        P A = pol[i], B = pol[(i + 1) % n];
        if (ccw(l[0], l[1], A) != -1) res.push_back(A);
        if (ccw(l[0], l[1], A) * ccw(l[0], l[1], B) < 0) res.push_back(crosspointLL(L(A, B), l));
    }
    return res;
}
//凸多角形の切断終.

// 最近点対.
// O(N log N)
// [半開区間)iter渡し, x座標昇順.
// 凸多角形の直径と競合.
template <class iter>
std::tuple<ld, P, P> closest_pair(iter left, iter right) {
    int n = distance(left, right);

    if (n == 1) {
        return std::make_tuple(std::numeric_limits<ld>::max(), *left, *left);
    }

    if (n == 2) {
        if (left[0].imag() > left[1].imag()) swap(left[0], left[1]);
        return std::make_tuple(norm(left[0] - left[1]), left[0], left[1]);
    }

    iter middle = std::next(left, n / 2);
    ld x = middle->real();
    auto d = std::min(closest_pair(left, middle), closest_pair(middle, right));
    std::inplace_merge(left, middle, right,
                       [](const P &a, const P &b) { return a.imag() < b.imag(); });

    std::vector<iter> around;
    for (iter i = left; i != right; ++i) {
        ld dx = fabs(i->real() - x);
        ld &opt = std::get<0>(d);
        if (dx * dx >= opt) continue;
        for (auto j = around.rbegin(); j != around.rend(); ++j) {
            ld dx = i->real() - (**j).real();
            ld dy = i->imag() - (**j).imag();
            if (dy * dy >= opt) break;
            ld norm = dx * dx + dy * dy;
            if (opt > norm) {
                d = std::make_tuple(norm, *i, **j);
            }
        }
        around.push_back(i);
    }
    return d;
};

// 最近点対 終.

// P:点 point x: .real() y: .imag()
// L:直線 lineF
// S:線分 section
// G:多角形 vector<P>

signed main() {
    int N;
    cin >> N;
    G g(N);
    rep(i, N){
        ld xi, yi;
        cin >> xi >> yi;
        g[i] = P(xi, yi);
    }
    cout << fixed << setprecision(10);
    sort(all(g));
    cout << sqrt(get<0>(closest_pair(g.begin(), g.end()))) << endl;
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 11196
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i< (n); ++i)
#define repi(i, a, b) for (int i = (a); i < (b); ++i)
#define all(x) (x).begin(), (x).end()
#define fore(i, a) for(auto &i:a)
using ll = long long;
using int64 = long long;
#define DEBUG(x) cerr << #x << ": "; for (auto _ : x) cerr << _ << " "; cerr << endl;
const int64 infll = (1LL << 62) - 1;
const int inf = (1 << 30) - 1;

struct IoSetup {
	IoSetup() {
		cin.tie(nullptr);
		ios::sync_with_stdio(false);
		cout << fixed << setprecision(10);
		cerr << fixed << setprecision(10);
	}
} iosetup;

template <typename T1, typename T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& p) {
	os << p.first << " " << p.second;
	return os;
}

template <typename T1, typename T2>
istream& operator>>(istream& is, pair<T1, T2>& p) {
	is >> p.first >> p.second;
	return is;
}

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	for (int i = 0; i < (int)v.size(); i++) {
		os << v[i] << (i + 1 != v.size() ? " " : "");
	}
	return os;
}

template <typename T>
istream& operator>>(istream& is, vector<T>& v) {
	for (T& in : v) is >> in;
	return is;
}

template <typename T1, typename T2>
inline bool chmax(T1& a, T2 b) {
	return a < b && (a = b, true);
}

template <typename T1, typename T2>
inline bool chmin(T1& a, T2 b) {
	return a > b && (a = b, true);
}

template <typename T = int64>
vector<T> make_v(size_t a) {
	return vector<T>(a);
}

template <typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
	return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T& t, const V& v) {
	t = v;
}

template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T& t, const V& v) {
	for (auto& e : t) fill_v(e, v);
}

template <typename F>
struct FixPoint : F {
	explicit FixPoint(F&& f) : F(std::forward<F>(f)) {}

	template <typename... Args>
		decltype(auto) operator()(Args&&... args) const {
			return F::operator()(*this, std::forward<Args>(args)...);
		}
};

template <typename F>
inline decltype(auto) MFP(F&& f) {
	return FixPoint<F>{std::forward<F>(f)};
}
//Geometry
namespace geometry {
using Real = double;
const Real EPS = 1e-15;
const Real PI = acos(static_cast<Real>(-1));

enum { OUT, ON, IN };

inline int sign(const Real& r) { return r <= -EPS ? -1 : r >= EPS ? 1 : 0; }

inline bool equals(const Real& a, const Real& b) { return sign(a - b) == 0; }
}  // namespace geometry

namespace geometry {
using Point = complex<Real>;

istream& operator>>(istream& is, Point& p) {
  Real a, b;
  is >> a >> b;
  p = Point(a, b);
  return is;
}

ostream& operator<<(ostream& os, const Point& p) {
  return os << real(p) << " " << imag(p);
}

Point operator*(const Point& p, const Real& d) {
  return Point(real(p) * d, imag(p) * d);
}

// rotate point p counterclockwise by theta rad
Point rotate(Real theta, const Point& p) {
  return Point(cos(theta) * real(p) - sin(theta) * imag(p),
               sin(theta) * real(p) + cos(theta) * imag(p));
}

Real cross(const Point& a, const Point& b) {
  return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point& a, const Point& b) {
  return real(a) * real(b) + imag(a) * imag(b);
}

bool compare_x(const Point& a, const Point& b) {
  return equals(real(a), real(b)) ? imag(a) < imag(b) : real(a) < real(b);
}

bool compare_y(const Point& a, const Point& b) {
  return equals(imag(a), imag(b)) ? real(a) < real(b) : imag(a) < imag(b);
}

using Points = vector<Point>;
}  // namespace geometry

namespace geometry {
struct Line {
  Point a, b;

  Line() = default;

  Line(const Point& a, const Point& b) : a(a), b(b) {}

  Line(const Real& A, const Real& B, const Real& C) {  // Ax+By=C
    if (equals(A, 0)) {
      assert(!equals(B, 0));
      a = Point(0, C / B);
      b = Point(1, C / B);
    } else if (equals(B, 0)) {
      a = Point(C / A, 0);
      b = Point(C / A, 1);
    } else if (equals(C, 0)) {
      a = Point(0, C / B);
      b = Point(1, (C - A) / B);
    } else {
      a = Point(0, C / B);
      b = Point(C / A, 0);
    }
  }

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

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

using Lines = vector<Line>;
}  // namespace geometry

namespace geometry {
struct Segment : Line {
  Segment() = default;

  using Line::Line;
};

using Segments = vector<Segment>;
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line& l, const Point& p) {
  auto t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
}  // namespace geometry

namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line& l, const Point& p) {
  return p + (projection(l, p) - p) * 2;
}
}  // namespace geometry

namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
constexpr int COUNTER_CLOCKWISE = +1;
constexpr int CLOCKWISE = -1;
constexpr int ONLINE_BACK = +2;   // c-a-b
constexpr int ONLINE_FRONT = -2;  // a-b-c
constexpr int ON_SEGMENT = 0;     // a-c-b
int ccw(const Point& a, Point b, Point c) {
  b = b - a, c = c - a;
  if (sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE;
  if (sign(cross(b, c)) == -1) return CLOCKWISE;
  if (sign(dot(b, c)) == -1) return ONLINE_BACK;
  if (norm(b) < norm(c)) return ONLINE_FRONT;
  return ON_SEGMENT;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool is_orthogonal(const Line& a, const Line& b) {
  return equals(dot(a.a - a.b, b.a - b.b), 0.0);
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool is_parallel(const Line& a, const Line& b) {
  return equals(cross(a.b - a.a, b.b - b.a), 0.0);
}
}  // namespace geometry

namespace geometry {
bool is_intersect_ss(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;
}
}  // namespace geometry
namespace geometry {
bool is_intersect_sp(const Segment& s, const Point& p) {
  return ccw(s.a, s.b, p) == ON_SEGMENT;
}
}  // namespace geometry

namespace geometry {
Point cross_point_ll(const Line& l, const Line& m) {
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if (equals(abs(A), 0) && equals(abs(B), 0)) return m.a;
  return m.a + (m.b - m.a) * B / A;
}
}  // namespace geometry
namespace geometry {
Real distance_sp(const Segment& s, const Point& p) {
  Point r = projection(s, p);
  if (is_intersect_sp(s, r)) return abs(r - p);
  return min(abs(s.a - p), abs(s.b - p));
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance_ss(const Segment& a, const Segment& b) {
  if (is_intersect_ss(a, b)) return 0;
  return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a),
              distance_sp(b, a.b)});
}
}  // namespace geometry
namespace geometry {
using Polygon = vector<Point>;
using Polygons = vector<Polygon>;
}  // namespace geometry

namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
Real area(const Polygon& p) {
  int n = (int)p.size();
  Real A = 0;
  for (int i = 0; i < n; ++i) {
    A += cross(p[i], p[(i + 1) % n]);
  }
  return A * 0.5;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool is_convex_polygon(const Polygon& p) {
  int n = (int)p.size();
  for (int i = 0; i < n; i++) {
    if (ccw(p[(i + n - 1) % n], p[i], p[(i + 1) % n]) == CLOCKWISE)
      return false;
  }
  return true;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
int contains(const Polygon& Q, const Point& p) {
  bool in = false;
  for (int i = 0; i < Q.size(); i++) {
    Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
    if (imag(a) > imag(b)) swap(a, b);
    if (sign(imag(a)) <= 0 && 0 < sign(imag(b)) && sign(cross(a, b)) < 0)
      in = !in;
    if (equals(cross(a, b), 0) && sign(dot(a, b)) <= 0) return ON;
  }
  return in ? IN : OUT;
}
}  // namespace geometry
namespace geometry {
int convex_polygon_contains(const Polygon& Q, const Point& p) {
  int N = (int)Q.size();
  Point g = (Q[0] + Q[N / 3] + Q[N * 2 / 3]) / 3.0;
  if (equals(imag(g), imag(p)) && equals(real(g), real(p))) return IN;
  Point gp = p - g;
  int l = 0, r = N;
  while (r - l > 1) {
    int mid = (l + r) / 2;
    Point gl = Q[l] - g;
    Point gm = Q[mid] - g;
    if (cross(gl, gm) > 0) {
      if (cross(gl, gp) >= 0 && cross(gm, gp) <= 0)
        r = mid;
      else
        l = mid;
    } else {
      if (cross(gl, gp) <= 0 && cross(gm, gp) >= 0)
        l = mid;
      else
        r = mid;
    }
  }
  r %= N;
  Real v = cross(Q[l] - p, Q[r] - p);
  return sign(v) == 0 ? ON : sign(v) == -1 ? OUT : IN;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
Polygon convex_hull(Polygon& p, bool strict = true) {
  int n = (int)p.size(), k = 0;
  if (n <= 2) return p;
  sort(begin(p), end(p), compare_x);
  vector<Point> ch(2 * n);
  auto check = [&](int i) {
    return sign(cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1])) <= -1 + strict;
  };
  for (int i = 0; i < n; ch[k++] = p[i++]) {
    while (k >= 2 && check(i)) --k;
  }
  for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
    while (k >= t && check(i)) --k;
  }
  ch.resize(k - 1);
  return ch;
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B
pair<int, int> convex_polygon_diameter(const Polygon& p) {
  int N = (int)p.size();
  int is = 0, js = 0;
  for (int i = 1; i < N; i++) {
    if (imag(p[i]) > imag(p[is])) is = i;
    if (imag(p[i]) < imag(p[js])) js = i;
  }
  Real maxdis = norm(p[is] - p[js]);

  int maxi, maxj, i, j;
  i = maxi = is;
  j = maxj = js;
  do {
    if (cross(p[(i + 1) % N] - p[i], p[(j + 1) % N] - p[j]) >= 0) {
      j = (j + 1) % N;
    } else {
      i = (i + 1) % N;
    }
    if (norm(p[i] - p[j]) > maxdis) {
      maxdis = norm(p[i] - p[j]);
      maxi = i;
      maxj = j;
    }
  } while (i != is || j != js);
  return minmax(maxi, maxj);
}
}  // namespace geometry
namespace geometry {
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
// cut with a straight line l and return a convex polygon on the left
Polygon convex_polygon_cut(const Polygon& U, const Line& l) {
  Polygon ret;
  for (int i = 0; i < U.size(); i++) {
    const Point& now = U[i];
    const Point& nxt = U[(i + 1) % U.size()];
    auto cf = cross(l.a - now, l.b - now);
    auto cs = cross(l.a - nxt, l.b - nxt);
    if (sign(cf) >= 0) {
      ret.emplace_back(now);
    }
    if (sign(cf) * sign(cs) < 0) {
      ret.emplace_back(cross_point_ll(Line(now, nxt), l));
    }
  }
  return ret;
}
}  // namespace geometry
namespace geometry {
double closest_pair(Points &pts) {
	sort(pts.begin(), pts.end(), compare_x);
	vector<Point> buf(pts.size());
	auto dist2 = [](Point a, Point b){
		Point c = a-b;
		return c.real()*c.real()+c.imag()*c.imag();
	};
	function<double(int,int)> rec = [&](int l, int r) -> double {
		if (r - l <= 3) {
			double d2 = 1e300;
			for (int i = l; i < r; ++i)
				for (int j = i + 1; j < r; ++j)
					d2 = min(d2, dist2(pts[i], pts[j]));
			sort(pts.begin() + l, pts.begin() + r, compare_y);
			return d2;
		}

		int m = (l + r) / 2;
		double xmid = pts[m].real();
		double d2 = min(rec(l, m), rec(m, r));

		merge(pts.begin()+l, pts.begin()+m, pts.begin()+m, pts.begin()+r, buf.begin(), compare_y);
		copy(buf.begin(), buf.begin() + (r - l), pts.begin() + l);

		int sz = 0;
		for (int i = l; i < r; ++i) {
			if ((pts[i].real() - xmid) * (pts[i].real() - xmid) < d2)
				buf[sz++] = pts[i];
		}

		for (int i = 0; i < sz; ++i)
			for (int j = i - 1; j >= 0 && (buf[i].imag() - buf[j].imag()) * (buf[i].imag() - buf[j].imag()) < d2; --j)
				d2 = min(d2, dist2(buf[i], buf[j]));

		return d2;
	};

	return sqrt(rec(0, pts.size()));
}
}
using namespace geometry;
int main(){
	ll n; cin >> n;
	Points p(n);
	rep(i, n)cin >> p[i];
	cout << closest_pair(p) << endl;
}
accuracy: 1
time_ms: 60
memory_kb: 6308
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct Point {
    double x, y;
    Point(double x=0, double y=0): x(x), y(y) {}
};

inline double dist2(const Point &a, const Point &b) {
    double dx = a.x - b.x, dy = a.y - b.y;
    return dx * dx + dy * dy;
}

double closest_pair(vector<Point> &pts) {
    sort(pts.begin(), pts.end(), [](auto &a, auto &b){ return a.x < b.x; });
    vector<Point> buf(pts.size());

    function<double(int,int)> rec = [&](int l, int r) -> double {
        if (r - l <= 3) {
            double d2 = 1e300;
            for (int i = l; i < r; ++i)
                for (int j = i + 1; j < r; ++j)
                    d2 = min(d2, dist2(pts[i], pts[j]));
            sort(pts.begin() + l, pts.begin() + r, [](auto &a, auto &b){ return a.y < b.y; });
            return d2;
        }

        int m = (l + r) / 2;
        double xmid = pts[m].x;
        double d2 = min(rec(l, m), rec(m, r));

        merge(pts.begin()+l, pts.begin()+m, pts.begin()+m, pts.begin()+r, buf.begin(), [](auto &a, auto &b){ return a.y < b.y; });
        copy(buf.begin(), buf.begin() + (r - l), pts.begin() + l);

        int sz = 0;
        for (int i = l; i < r; ++i) {
            if ((pts[i].x - xmid) * (pts[i].x - xmid) < d2)
                buf[sz++] = pts[i];
        }

        for (int i = 0; i < sz; ++i)
            for (int j = i - 1; j >= 0 && (buf[i].y - buf[j].y) * (buf[i].y - buf[j].y) < d2; --j)
                d2 = min(d2, dist2(buf[i], buf[j]));

        return d2;
    };

    return sqrt(rec(0, pts.size()));
}

int main() {
    int N;
    cin >> N;
    vector<Point> P(N);
    for (auto &p : P) cin >> p.x >> p.y;
    cout << fixed << setprecision(10) << closest_pair(P) << endl;
}
accuracy: 1
time_ms: 80
memory_kb: 6304
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;

struct Point {
    double x, y;
    Point(double x=0, double y=0): x(x), y(y) {}
};

// 2点間の距離
double dist(const Point &a, const Point &b) {
    double dx = a.x - b.x, dy = a.y - b.y;
    return sqrt(dx * dx + dy * dy);
}

// 最近接ペア距離 (分割統治法)
double closest_pair(vector<Point> pts) {
    int n = pts.size();
    sort(pts.begin(), pts.end(), [](const Point& a, const Point& b){
        return a.x < b.x;
    });

    auto dfs = [&](auto self, int l, int r) -> double {
        if (r - l <= 3) {
            double d = 1e18;
            for (int i = l; i < r; ++i)
                for (int j = i + 1; j < r; ++j)
                    d = min(d, dist(pts[i], pts[j]));
            sort(pts.begin() + l, pts.begin() + r, [](const Point& a, const Point& b){
                return a.y < b.y;
            });
            return d;
        }

        int m = (l + r) / 2;
        double xmid = pts[m].x;
        double d = min(self(self, l, m), self(self, m, r));

        inplace_merge(pts.begin() + l, pts.begin() + m, pts.begin() + r, [](const Point& a, const Point& b){
            return a.y < b.y;
        });

        vector<Point> buf;
        for (int i = l; i < r; ++i) {
            if (fabs(pts[i].x - xmid) >= d) continue;
            for (int j = (int)buf.size() - 1; j >= 0; --j) {
                if (pts[i].y - buf[j].y >= d) break;
                d = min(d, dist(pts[i], buf[j]));
            }
            buf.push_back(pts[i]);
        }
        return d;
    };

    return dfs(dfs, 0, n);
}

int main() {
    int N;
    cin >> N;
    vector<Point> P(N);
    for (int i = 0; i < N; ++i) cin >> P[i].x >> P[i].y;

    cout << fixed << setprecision(10) << closest_pair(P) << endl;
}
accuracy: 1
time_ms: 90
memory_kb: 9324
final_rank: 8

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

void Solve() {
    int N;
    cin >> N;
    vector<pair<double,double>> P(N);
    rep(i,0,N) {
        double x, y;
        cin >> x >> y;
        P[i] = {x,y};
    }
    sort(ALL(P));
    auto Dist = [&](int i, int j) -> double {
        return (P[i].first - P[j].first) * (P[i].first - P[j].first) + (P[i].second - P[j].second) * (P[i].second - P[j].second);
    };
    auto Calc = [&](auto self, int L, int R) -> double {
        if (R - L == 1) return INF;
        if (R - L == 2) return Dist(L,L+1);
        int MID = (L+R) / 2;
        double Ret = min(self(self,L,MID), self(self,MID,R));
        vector<int> ord(R-L);
        iota(ALL(ord),L);
        sort(ALL(ord),[&](int i, int j){return P[i].second < P[j].second;});
        double MX = P[MID].first;
        vector<int> V;
        for (int i : ord) {
            if ((P[i].first - MX) * (P[i].first - MX) > Ret) continue;
            rrep(j,0,SZ(V)) {
                if ((P[i].second - P[V[j]].second) * (P[i].second - P[V[j]].second) > Ret) break;
                chmin(Ret, Dist(i,V[j]));
            }
            V.push_back(i);
        }
        return Ret;
    };
    double ANS = Calc(Calc,0,N);
    printf("%.12f\n", sqrt(ANS));
}

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
int _ = 1;
//cin >> _;
while(_--) {
    Solve();
}
}
accuracy: 1
time_ms: 110
memory_kb: 5812
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int                             long long
#define f(i, a, b)                      for (int i = (a); i <= (b); i++)
#define fd(i, a, b)                     for (int i = (a); i >= (b); i--)
#define minimize(a, b)                  (a) = ((a) < (b) ? (a) : (b))
#define maximize(a, b)                  (a) = ((a) > (b) ? (a) : (b)) 
#define fi                              first
#define se                              second
#define ll                              long long
#define pii                             pair <double, double>
#define pb                              push_back
#define pi                              acos(-1)
#define sz(a)                           (int)a.size()
#define getbit(a, b)                    (((a) >> (b)) & 1)
#define INOUT                           "main"
#define INFT                            0x3f3f3f3f

void file()
{
        ios_base::sync_with_stdio(false);
        cin.tie(NULL); cout.tie(NULL);
        if (fopen(INOUT".inp", "r")) 
        {
            freopen(INOUT".inp", "r", stdin); 
            freopen(INOUT".out", "w", stdout);
        }
}

const int MOD = 998244353;
const int MAX = 1e5 + 5;
const int INF = 1e18;
int n;
pii point[MAX];
double res = 1e18;

signed main()
{
        file();

        cin >> n;
        f(i, 1, n)      
                cin >> point[i].fi >> point[i].se;
        sort(point + 1, point + n + 1);

        set <pii> s;
        int j = 1;

        f(i, 1, n)      
        {
                while(j < i && point[j].fi < point[i].fi - res)
                {
                        s.erase({point[j].se, point[j].fi});
                        j ++;
                }

                auto [x, y] = point[i];
                auto it = s.lower_bound({y - res, -INF});
                
                while(it != s.end())
                {
                        if (it->fi >= y + res)   break;

                        double dx = x - it->se;
                        double dy = y - it->fi;

                        res = min(res, sqrt(dx * dx + dy * dy));
                        it ++;
                }

                s.insert({y, x});
        }       

        cout << fixed << setprecision(12) << res;

        return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 9904
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define int                             long long
#define f(i, a, b)                      for (int i = (a); i <= (b); i++)
#define fi                              first
#define se                              second

using pii = pair<double,double>;

const int MAX = 1e5 + 5;
const int INF = 1e6;
int n;
pii point[MAX];
double res = 1e18;

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    cin >> n;
    f(i, 1, n)
        cin >> point[i].fi >> point[i].se;
    sort(point + 1, point + n + 1);

    set<pii> s;
    int j = 1;

    f(i, 1, n)
    {
        // 1) đảm bảo chỉ xoá những điểm đã được thêm (j < i)
        while (j < i && (point[i].fi - point[j].fi) > res)
        {
            // 2) erase by value (an toàn nếu phần tử không tồn tại)
            s.erase({point[j].se, point[j].fi});
            j++;
        }

        auto [x, y] = point[i];
        // lower_bound: tìm phần tử có y >= y-res (chuyển thành double)
        auto it = s.lower_bound({y - res, -1e18});

        while (it != s.end())
        {
            if (it->fi > y + res) break;

            double dx = x - it->se;
            double dy = y - it->fi;
            double dis = sqrt(dx*dx + dy*dy);
            if (dis < res) res = dis;
            ++it;
        }

        s.insert({y, x});
    }

    cout.setf(std::ios::fixed); cout<<setprecision(12)<<res<<"\n";
    return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 10112
final_rank: 7

code_snippet: #include <bits/stdc++.h>
#define point pair<double, double>
#define x first
#define y second
using namespace std;

const double inf = 1e4;

int main() {
    int n;
    cin >> n;
    vector<point> p(n);
    for (int i = 0; i < n; i++)
        cin >> p[i].x >> p[i].y;

    sort(p.begin(), p.end());
    set<point> s;
    double d = inf;

    for (int i = 0, j = 0; i < n; i++) {
        while (p[j].x < p[i].x - d)
            s.erase(s.find(make_pair(p[j].y, p[j].x))), j++;

        for (auto it = s.lower_bound(make_pair(p[i].y - d, -inf));
             it != s.upper_bound(make_pair(p[i].y + d, inf)); it++) {
            double dx = p[i].x - it->second;
            double dy = p[i].y - it->first;
            d = min(d, sqrt(dx * dx + dy * dy));
        }

        s.insert({p[i].y, p[i].x});
    }

    cout << setprecision(12) << fixed;
    cout << d << "\n";
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 9984
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#ifndef ONLINE_JUDGE
#define _GLIBCXX_DEBUG
#include <iostream>
template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {return os<<'(' <<p.first<<", "<<p.second<<')';}
template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {os<<'[';for(auto it=v.begin();it!=v.end();++it){os<<*it; if(next(it)!=v.end()){os<<", ";}}return os<<']';}
template <typename T>
ostream& operator<<(ostream& os, const vector<vector<T>>& vv) {os<<"[\n";for(auto it=vv.begin();it!=vv.end();++it){os<<"  "<<*it;if(next(it)!=vv.end()){os<<",\n";}else{os<<"\n";}}return os<<"]";}
#define dump(x) cerr << #x << " = " << (x) << '\n'
#else
#define dump(x) (void)0
#endif
using ll = long long;
using ld = long double;
using P = pair<ll,ll>;
template<class T> using pq = priority_queue<T>;
template<class T> using pq_g = priority_queue<T, vector<T>, greater<T>>;
#define out(x) cout<<x<<'\n'
#define all(v) (v).begin(),(v).end()
#define rall(v) (v).rbegin(),(v).rend()
#define OVERLOAD_REP(_1,_2,_3,name,...) name
#define REP1(i,n) for (auto i = std::decay_t<decltype(n)>{}; (i) < (n); ++(i))
#define REP2(i, l, r) for (auto i = (l); (i) < (r); ++(i))
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__)
template<class T> inline bool chmin(T& a, T b) {if(a > b){a = b; return true;} else {return false;}};
template<class T> inline bool chmax(T& a, T b) {if(a < b){a = b; return true;} else {return false;}};
const ll INF=(1LL<<60);
const ll mod=998244353;
using Graph = vector<vector<ll>>;
using Network = vector<vector<pair<ll,ll>>>;
using Grid = vector<string>;
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int dx2[8] = {1, 1,  1, 0,  0, -1, -1, -1};
const int dy2[8] = {1, 0, -1, 1, -1,  1,  0, -1};

// #include "../geo.hpp"

#pragma once

using D = long double;
const D EPS = 1e-12L;
const D PI = acosl(-1.0L);
using P2 = complex<D>;
struct L2{P2 a, b;};
struct S2{P2 a, b;};
using G2 = vector<P2>;

int sgn(D x){return (x>EPS)-(x<-EPS);}
int cmp(D a, D b){return sgn(a-b);}
bool eq(D a, D b){return cmp(a, b)==0;}
bool lt(D a, D b){return cmp(a, b)<0;}
bool le(D a, D b){return cmp(a, b)<=0;}
bool gt(D a, D b){return cmp(a, b)>0;}
bool ge(D a, D b){return cmp(a, b)>=0;}
bool eqP2(P2 a, P2 b){return eq(real(a), real(b)) && eq(imag(a), imag(b));}
bool ltP2(P2 a, P2 b) {
    return lt(real(a), real(b)) || (eq(real(a), real(b)) && lt(imag(a), imag(b)));
}

D dot(P2 a, P2 b) {return real(conj(a)*b);}
D cross(P2 a, P2 b) {return imag(conj(a)*b);}
int ccw(P2 a, P2 b, P2 c) {
    b-=a; c-=a;
    auto cr=cross(b, c), dt=dot(b, c);
    if (cr > EPS) return +1;       // counter clockwise
    if (cr < -EPS) return -1;      // clockwise
    if (dt < -EPS) return +2;         // c--a--b
    if (lt(norm(b), norm(c))) return -2; // a--b--c
    return 0;                  // a--c--b
}
int turn(P2 a, P2 b, P2 c) { return sgn(cross(b - a, c - a)); }

P2 rot(P2 a, D th) { return a*polar<D>(1, th); }
P2 rot90(P2 a) { return P2(-imag(a), real(a)); }
bool ltP2Arg(P2 a, P2 b) {
    auto up = [](P2 p) { return (imag(p) > 0 || (eq(imag(p), 0) && ge(real(p), 0))); };
    if (up(a) != up(b)) return up(a);
    if (!eq(cross(a, b), 0)) return cross(a, b) > 0;
    return lt(norm(a), norm(b));
}

inline void rd(P2& p) {D x, y; cin>>x>>y; p = P2(x, y);}
#define setp(n) cout<<setprecision(n)<<fixed
inline void pr(const P2& p) {setp(12); cout<<real(p)<<' '<<imag(p)<<'\n';}

// ----------------------------------------------------------------------------------

P2 proj(L2 l, P2 p) { P2 a=p-l.a, b=l.b-l.a; return l.a+b*dot(a, b)/norm(b);}
P2 refl(L2 l, P2 p) { return proj(l, p)*2.0L - p; }
bool isParallel(L2 l, L2 m){ return eq(cross(l.a-l.b, m.a-m.b), 0); }
bool isPerp(L2 l, L2 m){ return eq(dot(l.a-l.b, m.a-m.b), 0); }

bool isLL(L2 l, L2 m){ return !eq(cross(l.a-l.b, m.a-m.b), 0); }
bool isLS(L2 l, S2 s){ return turn(l.a, l.b, s.a)*turn(l.a, l.b, s.b)<=0; }
bool isSS(S2 s, S2 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;
}

P2 cpLL(L2 l, L2 m) {
    P2 a=l.b-l.a, b=m.b-m.a;
    D d=cross(a, b);
    if (eq(d, 0)) return P2(INF, INF); // parallel
    return l.a + a*cross(m.b-l.a,b)/d;
}

D distLP(L2 l, P2 p) { return abs(cross(l.b-l.a, p-l.a))/abs(l.b-l.a); }
D distSP(S2 s, P2 p) {
    P2 a=s.a, b=s.b;
    if (lt(dot(b-a, p-a), 0)) return abs(p-a);
    if (lt(dot(a-b, p-b), 0)) return abs(p-b);
    return distLP({a,b}, p);
}
D distSS(S2 s, S2 t) {
    if (isSS(s, t)) return 0;
    return min({distSP(s, t.a), distSP(s, t.b), distSP(t, s.a), distSP(t, s.b)});
}

D area(G2 g) {
    D s=0;
    int n=g.size();
    rep(i, n) s+=cross(g[i], g[(i+1)%n]);
    return s/2.0L;
}

bool isConvex(G2 g) {
    int n=g.size();
    if (n < 3) return false;
    int dir = 0;
    rep(i,n){
        int s = turn(g[i], g[(i+1)%n], g[(i+2)%n]);
        if (s == 0) return false; // -> continue : allows three points on a line
        if (dir == 0) dir = s;
        else if (dir*s < 0) return false;
    }
    return true;
}

int inG(G2 g, P2 p) {
    bool in=false;
    int n=g.size();
    rep(i, n) {
        P2 a=g[i], b=g[(i+1)%n];
        if (ccw(a, b, p) == 0) return 1; // on boundary
        if (a.imag() > b.imag()) swap(a, b);
        if (le(a.imag(), p.imag()) && lt(p.imag(), b.imag()) && turn(a, b, p) > 0) in=!in;
    }
    return in ? 2 : 0; // inside : outside
}

G2 hull(G2 g) {
    sort(all(g), ltP2);
    g.erase(unique(all(g), eqP2), g.end());
    if (g.size()<=1) return g;
    G2 lo, up;
    for (auto &p:g) {
        while (lo.size()>=2 && turn(lo[lo.size()-2], lo.back(), p)<=0) lo.pop_back(); //-> turn()<0 : allow three points on a line
        lo.push_back(p);
    }
    reverse(all(g));
    for (auto &p:g) {
        while (up.size()>=2 && turn(up[up.size()-2], up.back(), p)<=0) up.pop_back(); // -> turn()<0 : allow three points on a line
        up.push_back(p);
    }
    lo.pop_back(); up.pop_back();
    lo.insert(lo.end(), all(up));
    return lo;
}

pair<P2, P2> diameter(const G2& h) {
    int n=h.size();
    if(n==0) return {P2(0,0), P2(0,0)};
    if(n==1) return {h[0], h[0]};
    auto area2=[&](int i, int j, int k) {return abs(cross(h[j]-h[i], h[k]-h[i]));};
    D maxd=0;
    pair<P2, P2> res={h[0], h[0]};
    int j=1;
    rep(i, n) {
        int ni=(i+1)%n;
        while (gt(area2(i, ni, (j+1)%n), area2(i, ni, j))) j=(j+1)%n;
        if (gt(abs(h[i]-h[j]), maxd)) maxd=abs(h[i]-h[j]), res={h[i], h[j]};
        if (gt(abs(h[ni]-h[j]), maxd)) maxd=abs(h[ni]-h[j]), res={h[ni], h[j]};
    }
    return res;
}

// int inConvex(G2 h, P2 p) {
//     int n=h.size();
//     if (n==0) return 0;
//     if (n==1) return eqP2(h[0], p) ? 2 : 0;
//     if (n==2) return ccw(h[0], h[1], p)==0 && le(abs(h[0]-p)+abs(h[1]-p), abs(h[0]-h[1])) ? 2 : 0;
//     int left=1, right=n-1;
//     while (right-left>1) {
//         int mid=(left+right)/2;
//         if (turn(h[0], h[mid], p)<0) right=mid;
//         else left=mid;
//     }
//     if (turn(h[0], h[left], p)<0) return 0;
//     if (turn(h[left], h[right%n], p)<0) return 0;
//     if (turn(h[right%n], h[0], p)<0) return 0;
//     if (turn(h[0], h[left], p)==0 || turn(h[left], h[right%n], p)==0 || turn(h[right%n], h[0], p)==0) return 2;
//     return 1;
// }

G2 cutConvex(G2 h, L2 l) {
    int n=h.size();
    G2 res;
    if (n==0) return res;
    auto inside=[&](P2 p){ return turn(l.a, l.b, p) >= 0; };
    rep(i, n) {
        P2 a=h[i], b=h[(i+1)%n];
        bool ina=inside(a), inb=inside(b);
        if (ina&&inb) res.push_back(b);
        else if (ina&&!inb) {
            res.push_back(proj({a,b}, l.a));
        }
        else if (!ina&&inb) {
            res.push_back(proj({a,b}, l.a));
            res.push_back(b);
        }
    }
    return res;
}


pair<P2, P2> closestPair(G2 g) {
    auto ps = g;
    int n=ps.size();
    if (n < 2) return {P2(0,0), P2(0,0)};
    sort(all(ps), ltP2);
    D mind = norm(ps[0]-ps[1]);
    pair<P2, P2> res = {ps[0], ps[1]};
    set<pair<D,int>> box;
    int j=0;
    rep(i, n) {
        D xi=real(ps[i]), yi=imag(ps[i]);
        D rad = sqrtl(mind);
        while (j<i && gt(xi - real(ps[j]), rad)) {
            box.erase({imag(ps[j]), j});
            j++;
        }
        auto it = box.lower_bound({yi - rad, -1});
        for (; it != box.end() && le(it->first, yi + rad); ++it) {
            int k = it->second;
            D d = norm(ps[i]-ps[k]);
            if (lt(d, mind)) mind=d, res={ps[i], ps[k]}, rad = sqrtl(mind);
        }
        box.insert({yi, i});
    }
    return res;
}


struct C2 { P2 o; D r; };

C2 makeC2(P2 a, P2 b) {
    return C2{(a+b)/D(2), abs(a-b)/D(2)};
}
C2 makeC2(P2 a, P2 b, P2 c) {
    P2 B=b-a, C=c-a;
    D d=2*cross(B, C);
    if (eq(d, 0)) {
        D ab=norm(B), bc=norm(b-c), ca=norm(c-a);
        if (le(ab, bc) && le(ab, ca)) return makeC2(a, b);
        if (le(bc, ca)) return makeC2(b, c);
        return makeC2(c, a);
    }
    P2 o=a+(rot90(B)*norm(C)-rot90(C)*norm(B))/d;
    return C2{o, abs(o-a)};
}

C2 incircle(P2 a, P2 b, P2 c) {
    D ab=abs(b-a), bc=abs(c-b), ca=abs(a-c);
    P2 o=(a*bc+b*ca+c*ab)/(ab+bc+ca);
    D r=abs(cross(b-a, o-a))/abs(b-a);
    return C2{o, r};
}

vector<P2> cpCL(L2 l, C2 c) {
    vector<P2> res;
    P2 a=l.a-c.o, d=l.b-l.a;
    D A=norm(d), B=2*dot(a, d), C=norm(a)-c.r*c.r;
    D Dlt=B*B-4*A*C;
    if (lt(Dlt, 0)) return res;
    D s = le(Dlt, 0) ? 0 : sqrtl(max<D>(0, Dlt));
    D t1 = (-B - s)/(2*A), t2 = (-B + s)/(2*A);
    res.push_back(c.o + a + d*t1);
    if (gt(Dlt, 0)) res.push_back(c.o + a + d*t2);
    return res;
}

vector<P2> cpCC(C2 c1, C2 c2) {
    vector<P2> res;
    P2 d=c2.o-c1.o;
    D L=abs(d);
    if (eq(L, 0)) return res;
    D a=(c1.r*c1.r-c2.r*c2.r+L*L)/(2*L), h2=c1.r*c1.r-a*a;
    if (lt(h2, 0)) return res;
    P2 m=c1.o+d*(a/L), n=rot90(d)*( (lt(h2, 0) ? 0 : sqrtl(max<D>(0, h2))/L) );
    res.push_back(m-n);
    if (gt(h2, 0)) res.push_back(m+n);
    return res;
}

D isaCC(C2 c1, C2 c2) {
    D d=abs(c1.o-c2.o), r1=c1.r, r2=c2.r;
    if (ge(d, r1+r2)) return 0;
    if (le(d, abs(r1-r2))) {
        D r=min(r1, r2);
        return PI*r*r;
    }
    auto f = [&] (D z) { return max<D>(-1, min<D>(1, z)); };
    D a = 2*acosl(f((d*d+r1*r1-r2*r2)/(2*d*r1)));
    D b = 2*acosl(f((d*d+r2*r2-r1*r1)/(2*d*r2)));
    return 0.5L*(r1*r1*(a-sinl(a)) + r2*r2*(b-sinl(b)));
}

vector<L2> tangCP(C2 c, P2 p) {
    vector<L2> res;
    P2 v = p - c.o;
    D d2 = norm(v), r2 = c.r*c.r;
    if (lt(d2, r2)) return res;
    if (eq(d2, r2)) {
        res.push_back({c.o+v*(r2/d2), p});
        return res;
    }
    D h = c.r*sqrtl(max<D>(0, d2 - r2));
    P2 n1 = (v*r2 - rot90(v)*h)/d2;
    P2 n2 = (v*r2 + rot90(v)*h)/d2;
    res.push_back({c.o+n1, p});
    res.push_back({c.o+n2, p});
    return res;
}

vector<L2> tangCC(C2 c1, C2 c2) {
    vector<L2> res;
    P2 d = c2.o-c1.o;
    D L=abs(d);
    if (eq(L, 0)) return res;
    P2 e = d/L;
    auto add = [&] (int s) {
        D c=(s*c2.r - c1.r)/L;
        if (gt(c*c, 1)) return;
        D s2 = max<D>(0, 1 - c*c);
        if (eq(s2, 0)) {
            P2 n = e*c;
            res.push_back({c1.o-n*c1.r, c2.o-n*c2.r});
        } else {
            D s = sqrtl(s2);
            P2 n1 = e*c + rot90(e)*s;
            P2 n2 = e*c - rot90(e)*s;
            res.push_back({c1.o-n1*c1.r, c2.o-n1*c2.r});
            res.push_back({c1.o-n2*c1.r, c2.o-n2*c2.r});
        }
    };
    add(+1); // external
    add(-1); // internal
    return res;
}

C2 mec(G2 ps) {
    auto inC2=[&](C2 c, P2 p){ return le(abs(c.o - p), c.r); };
    mt19937_64 rng((uint64_t)chrono::steady_clock::now().time_since_epoch().count());
    shuffle(all(ps), rng);
    int n=ps.size();
    if(n==0) return C2{P2(0,0), 0};
    C2 c{ps[0], 0};
    rep(i, n) {
        if (inC2(c, ps[i])) continue;
        c={ps[i], 0};
        rep(j, i) {
            if (inC2(c, ps[j])) continue;
            c=makeC2(ps[i], ps[j]);
            rep(k, j) {
                if (inC2(c, ps[k])) continue;
                c=makeC2(ps[i], ps[j], ps[k]);
            }
        }
    }
    return c;
}

vector<P2> cpSegs(vector<S2> ss) {
    struct E { D x; int t; D y, y1, y2; }; // t: 0=add(H), 1=query(V), 2=remove(H)
    vector<E> es; es.reserve(ss.size()*2);

    for(auto s: ss) {
        if (eq(s.a.imag(), s.b.imag())) {
            if (gt(s.a.real(), s.b.real())) swap(s.a, s.b);
            es.push_back({s.a.real(), 0, s.a.imag(), 0, 0});
            es.push_back({s.b.real(), 2, s.a.imag(), 0, 0});
        } else {
            if (gt(s.a.imag(), s.b.imag())) swap(s.a, s.b);
            es.push_back({s.a.real(), 1, 0, s.a.imag(), s.b.imag()});
        }
    }

    sort(all(es), [](E a, E b) {
        if (!eq(a.x, b.x)) return lt(a.x, b.x);
        return a.t < b.t;
    });

    multiset<D> active;
    vector<P2> res; res.reserve(ss.size());
    for (auto e : es) {
        if (e.t == 0) { // add
            active.insert(e.y);
        } else if (e.t == 2) { // remove
            auto it = active.find(e.y);
            if (it != active.end()) active.erase(it);
        } else { // query
            for (auto it = active.lower_bound(e.y1); it != active.end() && le(*it, e.y2); ++it) {
                res.push_back(P2(e.x, *it));
            }
        }
    }

    sort(all(res), ltP2);
    res.erase(unique(all(res), eqP2), res.end());
    return res;
}


// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_A
void Projection() {
    P2 a, b; rd(a); rd(b);
    L2 l = {a, b};
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        pr(proj(l, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_B
void Reflection() {
    P2 a, b; rd(a); rd(b);
    L2 l = {a, b};
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        pr(refl(l, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_1_C
void CounterClockwise() {
    P2 p0, p1;
    rd(p0); rd(p1);
    ll q; cin>>q;
    while(q--) {
        P2 p; rd(p);
        int res = ccw(p0, p1, p);
        if (res == +1) out("COUNTER_CLOCKWISE");
        else if (res == -1) out("CLOCKWISE");
        else if (res == +2) out("ONLINE_BACK");
        else if (res == -2) out("ONLINE_FRONT");
        else out("ON_SEGMENT");
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/1/CGL_2_A
void ParallelOrthogonal() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        if (isParallel({p1, p2}, {p3, p4})) out(2);
        else if(isPerp({p1, p2}, {p3, p4})) out(1);
        else out(0);
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_B
void IntersectionSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        S2 s1 = {p1, p2}, s2 = {p3, p4};
        out(isSS(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_C
void CrossPointSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        L2 s1 = {p1, p2}, s2 = {p3, p4};
        pr(cpLL(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/2/CGL_2_D
void DistanceSS() {
    ll q;cin>>q;
    while(q--) {
        P2 p1, p2, p3, p4;
        rd(p1); rd(p2); rd(p3); rd(p4);
        S2 s1 = {p1, p2}, s2 = {p3, p4};
        setp(12);
        out(distSS(s1, s2));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_A
void Area() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    setp(1);
    out(area(g));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_B
void IsConvex() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    out(isConvex(g));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/3/CGL_3_C
void PolygonPointContainment() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    ll q;cin>>q;
    while(q--) {
        P2 p; rd(p);
        out(inG(g, p));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_A
void ConvexHull() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    G2 h = hull(g);
    out(h.size());
    ll sx = INF, sy = INF;
    ll id = -1;
    rep(i, h.size()) {
        if (lt(imag(h[i]), sy)) {
            sx = real(h[i]);
            sy = imag(h[i]);
            id = i;
        }
        else if (eq(imag(h[i]), sy) && lt(real(h[i]), sx)) {
            sx = real(h[i]);
            sy = imag(h[i]);
            id = i;
        }
    }
    rep(i, h.size()) {
        ll ni = (id + i) % h.size();
        pr(h[ni]);
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_B
void DiameterOfConvexPolygon() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [p1, p2] = diameter(g);
    setp(12);
    out(abs(p1 - p2));
    // todo
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/4/CGL_4_C
void ConvexCut() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    ll q;cin>>q;
    while(q--) {
        P2 a, b; rd(a); rd(b);
        L2 l = {a, b};
        G2 h = cutConvex(g, l);
        setp(12);
        out(area(h));
    }
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/5/CGL_5_A
void ClosestPair() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [p1, p2] = closestPair(g);
    setp(12);
    out(abs(p1 - p2));
}

// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/5/CGL_5_B
void MinimumEnclosingCircle() {
    ll n;cin>>n;
    G2 g(n);
    rep(i, n) rd(g[i]);
    auto [c, r] = mec(g);
    pr(c);
    setp(12);
    out(r);
}


// https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/6/CGL_6_A
void SegmentIntersections() {
    ll n;cin>>n;
    vector<S2> seg(n);
    rep(i, n) {
        P2 a, b; rd(a); rd(b);
        seg[i] = {a, b};
    }
    out(cpSegs(seg).size());
}


// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_A
void IntersectionOfCircles() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    out(tangCC(c1, c2).size());
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_B
void IncircleOfTriangle() {
    P2 a, b, c; rd(a); rd(b); rd(c);
    auto [ic, ir] = incircle(a, b, c);
    pr(ic);
    setp(12);
    out(ir);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_C
void CircumscribedCircleOfTriangle() {
    P2 a, b, c; rd(a); rd(b); rd(c);
    auto [cc, cr] = makeC2(a, b, c);
    pr(cc);
    setp(12);
    out(cr);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_D
void CrossPointsCL() {
    P2 c; D r;
    rd(c); cin>>r;
    ll q;cin>>q;
    while(q--) {
        P2 a, b; rd(a); rd(b);
        L2 l = {a, b};
        auto ps = cpCL(l, {c, r});
        sort(all(ps), ltP2);
        pr(ps[0]);
        pr(ps[(ps.size()-1)]);
    }
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_E
void CrossPointsCC() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    auto ps = cpCC(c1, c2);
    sort(all(ps), ltP2);
    pr(ps[0]);
    pr(ps[(ps.size()-1)]);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_F
void TangentToCircle() {
    P2 p, c; D r;
    rd(p);
    rd(c); cin>>r;
    C2 c1={c, r};
    auto ls = tangCP(c1, p);
    vector<P2> ps;
    for (auto l : ls) {
        ps.push_back(l.a);
    }
    sort(all(ps), ltP2);
    for (auto p : ps) pr(p);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_G
void CommonTangent() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    auto ls = tangCC(c1, c2);
    vector<P2> ps;
    for (auto l : ls) {
        ps.push_back(l.a);
    }
    sort(all(ps), ltP2);
    for (auto p : ps) pr(p);
}

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_H
// void IntersectionCP() {
//     ll n;cin>>n;
//     D r; cin>>r;
//     C2 c = {P2(0, 0), r};
//     G2 g(n);
//     rep(i, n) rd(g[i]);
//     out(isaCP(c, g));
// }

// // https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/7/CGL_7_I
void AreaOfIntersectionBetweenTwoCircles() {
    P2 o1, o2; D r1, r2;
    rd(o1); cin>>r1;
    rd(o2); cin>>r2;
    C2 c1={o1, r1}, c2={o2, r2};
    setp(12);
    out(isaCC(c1, c2));
}

int main() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);

    // Projection();
    // Reflection();
    // CounterClockwise();

    // ParallelOrthogonal();
    // IntersectionSS();
    // CrossPointSS();
    // DistanceSS();

    // Area();
    // IsConvex();
    // PolygonPointContainment();

    // ConvexHull();
    // DiameterOfConvexPolygon();
    // ConvexCut();

    ClosestPair();
    // MinimumEnclosingCircle();

    // SegmentIntersections();

    // IntersectionOfCircles();
    // IncircleOfTriangle();
    // CircumscribedCircleOfTriangle();
    // CrossPointsCL();
    // CrossPointsCC();
    // TangentToCircle();
    // CommonTangent();
    // IntersectionCP();
    // AreaOfIntersectionBetweenTwoCircles();
    return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 17944
final_rank: 19

code_snippet: #include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <climits>
#include <unordered_map>
#include <queue>
#include <deque>
#include <math.h>
#include <bits/stdc++.h>
#define ll long long
#define Lt Line<T>
#define Pt Point<T>
using i64 = long long;
using namespace std;

const ll N=1e6+10,MOD=998244353;

typedef std::pair<ll,ll> pii;
typedef std::pair<ll,pii> piii;
//i64 n,m,k;

using ld = long double;
const ld PI = acos(-1);
const ld EPS = 1e-7;
const ld INF = numeric_limits<ld>::max();
#define cc(x) cout << fixed << setprecision(x);

ld fgcd(ld x, ld y) { // 实数域gcd
    return abs(y) < EPS ? abs(x) : fgcd(y, fmod(x, y));
}
template<class T, class S> bool equal(T x, S y) {
    return -EPS < x - y && x - y < EPS;
}
template<class T> int sign(T x) {
    if (-EPS < x && x < EPS) return 0;
    return x < 0 ? -1 : 1;
}

template<class T> struct Point { // 在C++17下使用 emplace_back 绑定可能会导致CE！
    T x, y;
    Point(T x_ = 0, T y_ = 0) : x(x_), y(y_) {} // 初始化
    template<class U> operator Point<U>() { // 自动类型匹配
        return Point<U>(U(x), U(y));
    }
    Point &operator+=(Point p) & { return x += p.x, y += p.y, *this; }
    Point &operator+=(T t) & { return x += t, y += t, *this; }
    Point &operator-=(Point p) & { return x -= p.x, y -= p.y, *this; }
    Point &operator-=(T t) & { return x -= t, y -= t, *this; }
    Point &operator*=(T t) & { return x *= t, y *= t, *this; }
    Point &operator/=(T t) & { return x /= t, y /= t, *this; }
    Point operator-() const { return Point(-x, -y); }
    friend Point operator+(Point a, Point b) { return a += b; }
    friend Point operator+(Point a, T b) { return a += b; }
    friend Point operator-(Point a, Point b) { return a -= b; }
    friend Point operator-(Point a, T b) { return a -= b; }
    friend Point operator*(Point a, T b) { return a *= b; }
    friend Point operator*(T a, Point b) { return b *= a; }
    friend Point operator/(Point a, T b) { return a /= b; }
    friend bool operator<(Point a, Point b) {
        return equal(a.x, b.x) ? a.y < b.y - EPS : a.x < b.x - EPS;
    }
    friend bool operator>(Point a, Point b) { return b < a; }
    friend bool operator==(Point a, Point b) { return !(a < b) && !(b < a); }
    friend bool operator!=(Point a, Point b) { return a < b || b < a; }
    friend auto &operator>>(istream &is, Point &p) {
        return is >> p.x >> p.y;
    }
    friend auto &operator<<(ostream &os, Point p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }
};
template<class T> struct Line {
    Point<T> a, b;
    Line(Point<T> a_ = Point<T>(), Point<T> b_ = Point<T>()) : a(a_), b(b_) {}
    template<class U> operator Line<U>() { // 自动类型匹配
        return Line<U>(Point<U>(a), Point<U>(b));
    }
    friend auto &operator<<(ostream &os, Line l) {
        return os << "<" << l.a << ", " << l.b << ">";
    }
};

using Pd = Point<ld>;
using Ld = Line<ld>;


template<class T> T cross(Point<T> a, Point<T> b) { // 叉乘
    return a.x * b.y - a.y * b.x;
}
template<class T> T cross(Point<T> p1, Point<T> p2, Point<T> p0) { // 叉乘 (p1 - p0) x (p2 - p0);
    return cross(p1 - p0, p2 - p0);
}


template<class T> T dot(Point<T> a, Point<T> b) { // 点乘
    return a.x * b.x + a.y * b.y;
}
template<class T> T dot(Point<T> p1, Point<T> p2, Point<T> p0) { // 点乘 (p1 - p0) * (p2 - p0);
    return dot(p1 - p0, p2 - p0);
}

// template <class T> ld dis(T x1, T y1, T x2, T y2) {
//     ld val = (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2);
//     return sqrt(val);
// }
// template <class T> ld dis(Point<T> a, Point<T> b) {
//     return dis(a.x, a.y, b.x, b.y);
// }

// template<class T> Point<T> rotate(Point<T> p1, Point<T> p2) { // 旋转
//     Point<T> vec = p1 - p2;
//     return {-vec.y, vec.x};
// }

// ld toDeg(ld x) { // 弧度转角度
//     return x * 180 / PI;
// }
// ld toArc(ld x) { // 角度转弧度
//     return PI / 180 * x;
// }

// Point<ld> rotate(Point<ld> p, ld rad) {
//     return {p.x * cos(rad) - p.y * sin(rad), p.x * sin(rad) + p.y * cos(rad)};
// }

// Point<ld> rotate(Point<ld> a, Point<ld> b, ld rad) {
//     ld x = (a.x - b.x) * cos(rad) + (a.y - b.y) * sin(rad) + b.x;
//     ld y = (b.x - a.x) * sin(rad) + (a.y - b.y) * cos(rad) + b.y;
//     return {x, y};
// }

// template<class T> bool onLine(Point<T> a, Point<T> b, Point<T> c) {
//     return sign(cross(b, a, c)) == 0;
// }
// template<class T> bool onLine(Point<T> p, Line<T> l) {
//     return onLine(p, l.a, l.b);
// }

// template<class T> bool pointOnLineLeft(Pt p, Lt l) {
//     return cross(l.b, p, l.a) > 0;
// }

// template<class T> bool pointOnLineSide(Pt p1, Pt p2, Lt vec) {
//     T val = cross(p1, vec.a, vec.b) * cross(p2, vec.a, vec.b);
//     return sign(val) == 1;
// }
// template<class T> bool pointNotOnLineSide(Pt p1, Pt p2, Lt vec) {
//     T val = cross(p1, vec.a, vec.b) * cross(p2, vec.a, vec.b);
//     return sign(val) == -1;
// }

// Pd lineIntersection(Ld l1, Ld l2) {
//     ld val = cross(l2.b - l2.a, l1.a - l2.a) / cross(l2.b - l2.a, l1.a - l1.b);
//     return l1.a + (l1.b - l1.a) * val;
// }

// template<class T> bool lineParallel(Lt p1, Lt p2) {
//     return sign(cross(p1.a - p1.b, p2.a - p2.b)) == 0;
// }
// template<class T> bool lineVertical(Lt p1, Lt p2) {
//     return sign(dot(p1.a - p1.b, p2.a - p2.b)) == 0;
// }
// template<class T> bool same(Line<T> l1, Line<T> l2) {
//     return lineParallel(Line{l1.a, l2.b}, {l1.b, l2.a}) &&
//            lineParallel(Line{l1.a, l2.a}, {l1.b, l2.b}) && lineParallel(l1, l2);
// }

// pair<Pd, ld> pointToLine(Pd p, Ld l) {
//     Pd ans = lineIntersection({p, p + rotate(l.a, l.b)}, l);
//     return {ans, dis(p, ans)};
// }

// template<class T> ld disPointToLine(Pt p, Lt l) {
//     ld ans = cross(p, l.a, l.b);
//     return abs(ans) / dis(l.a, l.b); // 面积除以底边长
// }

// template<class T> bool pointOnSegment(Pt p, Lt l) { // 端点也算作在直线上
//     return sign(cross(p, l.a, l.b)) == 0 && min(l.a.x, l.b.x) <= p.x && p.x <= max(l.a.x, l.b.x) &&
//            min(l.a.y, l.b.y) <= p.y && p.y <= max(l.a.y, l.b.y);
// }

// pair<Pd, ld> pointToSegment(Pd p, Ld l) {
//     if (sign(dot(p, l.b, l.a)) == -1) { // 特判到两端点的距离
//         return {l.a, dis(p, l.a)};
//     } else if (sign(dot(p, l.a, l.b)) == -1) {
//         return {l.b, dis(p, l.b)};
//     }
//     return pointToLine(p, l);
// }

// template<class T> bool segmentIntersection(Lt l1, Lt l2) {
//     auto [s1, e1] = l1;
//     auto [s2, e2] = l2;
//     auto A = max(s1.x, e1.x), AA = min(s1.x, e1.x);
//     auto B = max(s1.y, e1.y), BB = min(s1.y, e1.y);
//     auto C = max(s2.x, e2.x), CC = min(s2.x, e2.x);
//     auto D = max(s2.y, e2.y), DD = min(s2.y, e2.y);
//     return A >= CC && B >= DD && C >= AA && D >= BB &&
//            sign(cross(s1, s2, e1) * cross(s1, e1, e2)) == 1 &&
//            sign(cross(s2, s1, e2) * cross(s2, e2, e1)) == 1;
// }

// template<class T> int pointInPolygon(Point<T> a, vector<Point<T>> p) {
//     int n = p.size();
//     for (int i = 0; i < n; i++) {
//         if (pointOnSegment(a, Line{p[i], p[(i + 1) % n]})) {
//             return 2;
//         }
//     }
//     int t = 0;
//     for (int i = 0; i < n; i++) {
//         auto u = p[i], v = p[(i + 1) % n];
//         if (u.x < a.x && v.x >= a.x && pointOnLineLeft(a, Line{v, u})) {
//             t ^= 1;
//         }
//         if (u.x >= a.x && v.x < a.x && pointOnLineLeft(a, Line{u, v})) {
//             t ^= 1;
//         }
//     }
//     return t == 1;
// }

// template<class T> bool cmp1(Point<T> &a,Point<T> &b)
// {
//     Point<T> a1(a.y,a.x);
//     Point<T> b1(b.y,b.x);
//     return a1<b1;
// }

// template<class T> vector<Point<T>> staticConvexHull(vector<Point<T>> A, int flag = 1) {
//     int n = A.size();
//     if (n <= 2) { // 特判
//         return A;
//     }
//     vector<Point<T>> ans(n * 2);
//     sort(A.begin(), A.end());
//     int now = -1;
    
//     for (int i = 0; i < n; i++) { // 维护下凸包
//         while (now > 0 && cross(A[i], ans[now], ans[now - 1]) <= 0) {
//             now--;
//         }
//         ans[++now] = A[i];
//     }
//     int pre = now;
//     for (int i = n - 2; i >= 0; i--) { // 维护上凸包
//         while (now > pre && cross(A[i], ans[now], ans[now - 1]) <= 0) {
//             now--;
//         }
//         ans[++now] = A[i];
//     }
//     ans.resize(now);
//     return ans;
// }

// template<class T>T GetConvexHullDis(vector<Pt> A)
// {
//     int w=0; 
//     T ans=max(dis(A[w],A[0]),dis(A[w],A[1]));
//     for(int i=0;i<A.size();i++)
//     {
//         int j=(i+1)%A.size();
//         int ne=(w+1)%A.size();
//         while(cross(A[ne],A[i],A[j])>=cross(A[w],A[i],A[j])) w=ne,ne=(w+1)%A.size();
//         ans=max(max(dis(A[w],A[i]),dis(A[w],A[j])),ans);
//     }
//     return ans;
// }

// vector<Pd> GetLineCrossHull(Ld L1,vector<Pd> A)
// {
//     vector<Pd> ans;
//     for(int i=0;i<A.size();i++)
//     {
//         Pd a1=A[i]; Pd a2=A[(i+1)%A.size()];
//         bool f1=pointOnLineLeft(a1,L1);
//         bool f2=pointOnLineLeft(a2,L1);
//         if(f1) ans.push_back(a1);
//         if(f1==f2) continue;
//         Ld tem(a1,a2);
//         ans.push_back(lineIntersection(tem,L1));
//     }
//     return ans;
// }

// template<class T> ld area(vector<Point<T>> P) {
//     int n = P.size();
//     ld ans = 0;
//     for (int i = 0; i < n; i++) {
//         ans += cross(P[i], P[(i + 1) % n]);
//     }
//     return ans / 2.0;
// }

template<class T> T sqr(T x) {
    return x * x;
}

template<class T> T disEx(Pt a1,Pt a2)
{
    return (a1.x-a2.x)*(a1.x-a2.x)+(a1.y-a2.y)*(a1.y-a2.y);
}

template<class T> T ClosestPairDis(vector<Pt> A)
{
    sort(A.begin(),A.end());
    T ans=disEx(A[0],A[1]);
    set<Pt> S;
    for(int i=0,h=0;i<A.size();i++)
    {
        Pt now={A[i].y,A[i].x};
        while(ans&&ans<=sqr(A[i].x-A[h].x))
        {
            S.erase({A[h].y,A[h].x});
            ++h;
        }
        auto it=S.lower_bound(now);
        for(auto k=it;k!=S.end()&&sqr(k->x-now.x)<ans;k++) ans=min(ans,disEx(*k,now));
        if(it!=S.begin())
        {
            for(auto k=prev(it);sqr(k->x-now.x)<ans;k--)
            {
                ans=min(ans,disEx(*k,now));
                if(k==S.begin()) break;
            }
        }
        S.insert(now);
    }
    return sqrt(ans);
}


int main() {
    
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);


    cc(12);
    int n;
    cin>>n;
    vector<Pd> z(n);
    for(auto &t:z) cin>>t;
    cout<<ClosestPairDis(z)<<'\n';


    return 0;
}
accuracy: 1
time_ms: 50
memory_kb: 15456
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long 
#define endl '\n'

#define maxn 200010


struct Point{
    double x,y;
};vector<Point>p;
double ans = 1e18;
typedef vector<Point>::iterator iter;
bool cmpx(const Point &a,const Point &b){
    if(a.x!=b.x)return a.x<b.x;
    return a.y<b.y;
}
bool cmpy(const Point &a,const Point &b){
    if(a.y!=b.y)return a.y<b.y;
    return a.x<b.x;
}
double dis(Point a,Point b){
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

void solve(const iter l,const iter r,double &d){
    if(r-l<=1)return;
    vector<Point>Q;
    iter mid = l+(r-l)/2;
    double w = mid->x;
    solve(l,mid,d);
    solve(mid,r,d);
    inplace_merge(l,mid,r,cmpy);
    for(iter i=l;i!=r;i++) if(abs(w-i->x)<=d) Q.push_back(*i);
    for(iter i=Q.begin(),j=i;i!=Q.end();i++){
        while(j!=Q.end()&&j->y<=i->y+d) j++;
        for(iter k=i+1;k!=j;k++) d=min(d,dis(*i,*k));
    }
}


signed main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    int n;
    cin>>n;
    for(int i =1;i<=n;i++){
        Point t;
        cin>>t.x>>t.y;
        p.push_back(t);
    }
    sort(p.begin(), p.end(), cmpx);
    solve(p.begin(),p.end(),ans);
    printf("%.10lf\n",ans);
}
accuracy: 1
time_ms: 60
memory_kb: 7904
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

using ld = long double;

struct Pt {
    ld x, y;
};

static inline ld dist2(const Pt& a, const Pt& b) {
    ld dx = a.x - b.x;
    ld dy = a.y - b.y;
    return dx*dx + dy*dy;
}

// Resolve [l, r) em pts (inicialmente ordenado por x).
// Retorna menor d^2 e mantém pts[l:r) ordenado por y ao terminar.
ld closest_rec(vector<Pt>& pts, int l, int r, vector<Pt>& tmp) {
    int n = r - l;
    if (n <= 3) {
        ld best = numeric_limits<ld>::infinity();
        for (int i = l; i < r; ++i)
            for (int j = i + 1; j < r; ++j)
                best = min(best, dist2(pts[i], pts[j]));
        // ordena por y
        sort(pts.begin() + l, pts.begin() + r, [](const Pt& a, const Pt& b){
            if (a.y != b.y) return a.y < b.y;
            return a.x < b.x;
        });
        return best;
    }
    int m = (l + r) >> 1;
    ld midx = pts[m].x;
    ld dl = closest_rec(pts, l, m, tmp);
    ld dr = closest_rec(pts, m, r, tmp);
    ld best = min(dl, dr);

    // merge por y (pts[l:m] e pts[m:r] já ordenados por y)
    int i = l, j = m, k = 0;
    while (i < m || j < r) {
        if (j == r || (i < m && (pts[i].y < pts[j].y || (pts[i].y == pts[j].y && pts[i].x < pts[j].x))))
            tmp[k++] = pts[i++];
        else
            tmp[k++] = pts[j++];
    }
    // copia de volta
    for (int t = 0; t < k; ++t) pts[l + t] = tmp[t];

    // strip: |x - midx| <= sqrt(best)
    ld d = sqrtl(best);
    vector<Pt> strip;
    strip.reserve(k);
    for (int t = l; t < r; ++t)
        if (fabsl(pts[t].x - midx) <= d) strip.push_back(pts[t]);

    // compara vizinhos na ordenação por y (while (dy^2 < best))
    for (size_t a = 0; a < strip.size(); ++a) {
        for (size_t b = a + 1; b < strip.size(); ++b) {
            ld dy = strip[b].y - strip[a].y;
            if (dy*dy >= best) break;
            best = min(best, dist2(strip[a], strip[b]));
        }
    }
    return best;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    if (!(cin >> n)) return 0;
    vector<Pt> pts(n);
    for (int i = 0; i < n; ++i) cin >> pts[i].x >> pts[i].y;

    // ordena por x, depois y para estabilidade
    sort(pts.begin(), pts.end(), [](const Pt& a, const Pt& b){
        if (a.x != b.x) return a.x < b.x;
        return a.y < b.y;
    });

    vector<Pt> tmp(n);
    ld best2 = closest_rec(pts, 0, n, tmp);
    ld ans = sqrtl(best2);

    cout.setf(std::ios::fixed); 
    cout << setprecision(10) << (double)ans << "\n";
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 12292
final_rank: 14

code_snippet: #include<bits/stdc++.h>
#define siz(x) int((x).size())
#define all(x) std::begin(x),std::end(x)
#define fi first
#define se second
using namespace std;
using unt=unsigned;
using loli=long long;
using lolu=unsigned long long;
using pii=pair<int,int>;
mt19937_64 rng(random_device{}());
constexpr double eps=1e-8;
template<typename any>inline any sqr(const any &x){return x*x;}
inline int get_op(double x){if(fabs(x)<eps)return 0;return x>0?1:-1;}
double det(array<double,3>a0,array<double,3>a1,array<double,3>a2){
	double sum=0;
	sum+=a0[0]*a1[1]*a2[2];
	sum+=a1[0]*a2[1]*a0[2];
	sum+=a2[0]*a0[1]*a1[2];
	sum-=a0[2]*a1[1]*a2[0];
	sum-=a0[1]*a1[0]*a2[2];
	sum-=a0[0]*a1[2]*a2[1];
	return sum;
}
struct bector{
	double x,y;
	bool operator<(const bector&t)const{return fabs(x-t.x)<eps?y<t.y:x<t.x;}
	bool operator==(const bector&t)const{return fabs(x-t.x)<eps&&fabs(y-t.y)<eps;}
	bector(double a=0,double b=0):x(a),y(b){}
	double operator~()const{return sqrt(x*x+y*y);}
	double operator*()const{return x*x+y*y;}
	friend istream&operator>>(istream&a,bector&b){return a>>b.x>>b.y;}
	friend ostream&operator<<(ostream&a,const bector&b){return a<<b.x<<' '<<b.y;}
	friend bector operator+(const bector&a,const bector&b){return {a.x+b.x,a.y+b.y};}
	bector&operator+=(const bector&t){x+=t.x,y+=t.y;return *this;}
	friend bector operator-(const bector&a,const bector&b){return {a.x-b.x,a.y-b.y};}
	bector&operator-=(const bector&t){x-=t.x,y-=t.y;return *this;}
	friend bector operator*(const bector&a,double b){return {a.x*b,a.y*b};}
	friend bector operator*(double b,const bector&a){return {a.x*b,a.y*b};}
	bector&operator*=(double t){x*=t,y*=t;return *this;}
	friend bector operator/(const bector&a,double b){return {a.x/b,a.y/b};}
	bector&operator/=(double t){x/=t,y/=t;return *this;}
	friend double operator*(const bector&a,const bector&b){return a.x*b.x+a.y*b.y;}
	friend double operator/(const bector&a,const bector&b){return a.x*b.y-a.y*b.x;}
	bool frontis(const bector&t)const{auto r=*this*t;return get_op(r)>0;}
	bool backis(const bector&t)const{auto r=*this*t;return get_op(r)<0;}
	bool leftis(const bector&t)const{auto r=*this/t;return get_op(r)>0;}
	bool rightis(const bector&t)const{auto r=*this/t;return get_op(r)<0;}
	bool front1s(const bector&t)const{auto r=*this*t;return get_op(r)>=0;}
	bool back1s(const bector&t)const{auto r=*this*t;return get_op(r)<=0;}
	bool left1s(const bector&t)const{auto r=*this/t;return get_op(r)>=0;}
	bool right1s(const bector&t)const{auto r=*this/t;return get_op(r)<=0;}
	friend double dis(const bector&a,const bector&b){return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}
	bector rot90()const{return {-y,x};}
	double arg()const{return atan2(y,x);}
	bector rotate(const bector&a,double r){
		auto u=a-*this;
		return *this+bector{u.x*cos(r)-u.y*sin(r),u.x*sin(r)+u.y*cos(r)};
	}
	friend double c0s(const bector&x,const bector&y){
		// 求 cos<x,y>
		return x*y/~x/~y;
	}
	bector unit()const{
		return (*this)/~(*this);
	}
	friend bool operator&(const bector&a,const bector&b){return !get_op(a*b);}
	friend bool operator|(const bector&a,const bector&b){return !get_op(a/b);}
	friend double triarea(const bector&x,const bector&y,const bector&z){
		return (y-x)/(z-x)/2;
	}
};
bector polar(double p,double r){return {cos(r)*p,sin(r)*p};}
struct segment{
	bector p1,p2;
	segment(const bector&a={0,0},const bector&b={0,0}):p1(a),p2(b){};
	friend istream&operator>>(istream&a,segment &b){return a>>b.p1>>b.p2;}
	friend ostream&operator<<(ostream&a,const segment&b){return a<<b.p1<<' '<<b.p2;}
	friend bool operator&(const segment&a,const segment&b){return !get_op((a.p2-a.p1)*(b.p2-b.p1));}
	friend bool operator|(const segment&a,const segment&b){return !get_op((a.p2-a.p1)/(b.p2-b.p1));}
	bool leftis(const bector&t)const{return (p2-p1).leftis(t-p1);}
	bool rightis(const bector&t)const{return (p2-p1).rightis(t-p1);}
	bool left1s(const bector&t)const{return (p2-p1).left1s(t-p1);}
	bool right1s(const bector&t)const{return (p2-p1).right1s(t-p1);}
	bool check(const bector&t)const{
		// cerr<<left1s(t)<<' '<<right1s(t)<<'\n';
		return left1s(t)&&right1s(t);
	}
	// bool check(const bector&t)const{return left1s(t)&&right1s(t);}
	friend bool banana(const segment&a,const segment&b){
		// 判断是否相交
		if(min(a.p1.x,a.p2.x)>max(b.p1.x,b.p2.x)||min(b.p1.x,b.p2.x)>max(a.p1.x,a.p2.x)||min(a.p1.y,a.p2.y)>max(b.p1.y,b.p2.y)||min(b.p1.y,b.p2.y)>max(a.p1.y,a.p2.y))return false;
		return get_op(((a.p2-a.p1)/(b.p1-a.p1))*((a.p2-a.p1)/(b.p2-a.p1)))<=0&&get_op(((b.p2-b.p1)/(a.p1-b.p1))*((b.p2-b.p1)/(a.p2-b.p1)))<=0;
	}
	friend bector focus(const segment&a,const segment&b){
		// 输入必须保证有交，输出交点
		bector v=a.p2-a.p1,w=b.p2-b.p1,u=a.p1-b.p1;
		return a.p1+v*((w/u)/(v/w));
	}
	friend double dis(const segment&a,const bector&b){
		if(a.p1==a.p2)return ~(b-a.p1);
		auto v1=a.p2-a.p1,v2=b-a.p1,v3=b-a.p2;
		if(v1.backis(v2))return ~v2;
		if(v1.frontis(v3))return ~v3;
		return fabs(v1/v2)/~v1;
	}
	friend double dis(const segment&a,const segment&b){
		// 求线段间最短距离
		if(banana(a,b))return 0;
		return min({dis(a,b.p1),dis(a,b.p2),dis(b,a.p1),dis(b,a.p2)});
	}
	bector project(const bector&a)const{
		// 求点 a 在当前线段上的投影点坐标
		if(a==p1||a==p2)return a;
		auto u=p2-p1,v=a-p1;
		return c0s(u,v)*(~v)*u.unit()+p1;
	}
	double pr0ject(const bector&a)const{
		return dis(a,project(a));
	}
	bector reflect(const bector&a)const{
		// 求点 a 在当前线段上的对称点
		return 2*project(a)-a;
	}
	segment&sort(){if(p2<p1)std::swap(p1,p2);return *this;}
};
struct circle{
	bector p;double r;
	circle(const bector&a={0,0},double b=0):p(a),r(b){}
	circle(bector p1,bector p2){
		p=(p1+p2)/2;
		r=dis(p1,p2)/2;
	}
	circle(bector p1,bector p2,bector p3){
		p.x=det({*p1,p1.y,1},{*p2,p2.y,1},{*p3,p3.y,1})/2/det({p1.x,p1.y,1},{p2.x,p2.y,1},{p3.x,p3.y,1});
		p.y=-det({*p1,p1.x,1},{*p2,p2.x,1},{*p3,p3.x,1})/2/det({p1.x,p1.y,1},{p2.x,p2.y,1},{p3.x,p3.y,1});
		r=dis(p,p1);
	}
	friend istream&operator>>(istream&a,circle &b){return a>>b.p>>b.r;}
	friend ostream&operator<<(ostream&a,const circle &b){return a<<b.p<<' '<<b.r;}
	bool check(bector t){
		return dis(p,t)-r<=eps;
	}
	friend segment focus(const circle &a,const segment&b){
		auto d=b.project(a.p),u=b.p2-b.p1,e=u/~u;
		auto t=sqrt(a.r*a.r-sqr(dis(d,a.p)));
		return segment{d+e*t,d-e*t}.sort();
	}
	friend segment focus(const circle &a,const circle &b){
		auto d=dis(a.p,b.p),l=acos((sqr(a.r)+sqr(d)-sqr(b.r))/(2*a.r*d)),t=(b.p-a.p).arg();
		return segment{a.p+polar(a.r,t+l),a.p+polar(a.r,t-l)}.sort();
	}
	segment tangent(const bector&a){
		auto u=a-p;
		auto l=acos(r/~u);
		u=u*r/~u;
		return segment{p.rotate(p+u,+l),p.rotate(p+u,-l)}.sort();
	}
};
struct points:vector<bector>{
#define p (*this)
	points&read(istream&t,int n=-1){
		if(n==-1)cin>>n;
		p.resize(n);
		for(int i=0;i<n;i++)t>>p[i];
		return *this;
	}
	double area()const{
		// 无需满足多边形是凸的
		double ans=0;
		for(int i=1;i<siz(p)-1;i++)ans+=(p[i]-p[0])/(p[i+1]-p[0]);
		return ans/2;
	}
	points tobag(){
		sort(all(p));
		erase(unique(all(p)),end());
		points b;
		for(int i=0;i<siz(p);i++){
			while(siz(b)>1&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<=0)
			// while(siz(b)>1&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<0)
				b.pop_back();
			b.push_back(p[i]);
		}
		int o=siz(b);
		for(int i=siz(p)-2;~i;i--){
			while(siz(b)>o&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<=0)
			// while(siz(b)>o&&get_op((b.back()-b[siz(b)-2])/(p[i]-b[siz(b)-2]))<0)
				b.pop_back();
			b.push_back(p[i]);
		}
		// if(siz(p)>1)b.pop_back();
		return b;
	}
	double xzqk()const{
		if(siz(p)==1)return 0;
		if(siz(p)==2)return dis(p[0],p[1]);
		if(siz(p)==3)return max({dis(p[0],p[1]),dis(p[0],p[2]),dis(p[1],p[2])});
		double ans=0;
		for(int i=1,j=2;i<siz(p);i++){
			while(get_op(triarea(p[i-1],p[i],p[j])-triarea(p[i-1],p[i],p[(j+1)%siz(p)]))<=0)
				(++j)%=siz(p);
			ans=max({ans,dis(p[i-1],p[j]),dis(p[i],p[j])});
		}
		return ans;
	}
	double kqzx(){
		sort(all(p));
		auto solve=[&](auto&&self,int l,int r){
			if(l==r)return 1e18;
			int mid=(l+r)/2;
			double ans=min(self(self,l,mid),self(self,mid+1,r));
			points b;
			for(int i=l;i<=r;i++)if(fabs(p[mid].x-p[i].x)<=ans)b.push_back(p[i]);
			sort(all(b),[](const bector&x,const bector&y){
				if(x.y==y.y)return x.x<y.x;
				return x.y<y.y;
			});
			for(int i=0;i<siz(b);i++)for(int j=i+1;j<siz(b);j++){
				if(b[j].y-b[i].y>=ans)break;
				ans=min(ans,dis(b[i],b[j]));
			}
			return ans;
		};
		return solve(solve,0,siz(p)-1);
	}
	circle incircle(){
		assert(siz(p)==3);
		auto u=p[1]-p[0],v=p[2]-p[0];u=u/~u*~v;
		segment l1{p[0],p[0]+u+v};
		u=p[2]-p[1],v=p[0]-p[1];u=u/~u*~v;
		segment l2{p[1],p[1]+u+v};
		auto pp=focus(l1,l2);
		return circle{pp,dis(segment{p[0],p[1]},pp)};
	}
	circle outcirce(){
		assert(siz(p)==3);
		auto u=p[1]-p[0],mid=(p[0]+p[1])/2;
		segment l1{mid,mid+u.rot90()};
		u=p[2]-p[0],mid=(p[0]+p[2])/2;
		segment l2{mid,mid+u.rot90()};
		auto pp=focus(l1,l2);
		return circle{pp,dis(p[0],pp)};
	}
	int contains(bector t){
		// 无需满足多边形是凸的
		// 2表示包含，1表示在边上，0表示在外面
		bool res=false;
		for(int i=0;i<siz(p);i++){
			auto a=p[i]-t,b=p[(i+1)%siz(p)]-t;
			if(!a.leftis(b)&&!a.rightis(b)&&!a.frontis(b))return 1;
			if(a.y>b.y)std::swap(a,b);
			if(a.y<eps&&eps<b.y&&a.leftis(b))res=!res;
		}
		return res?2:0;
	}
	points leftpoints(const segment&l)const{
		points b;
		// cerr<<"check "<<l<<'\n';
		for(int i=0;i<siz(p);i++){
			if(l.check(p[i]))b.push_back(p[i]);
			else if(l.rightis(p[(i-1+siz(p))%siz(p)])&&l.leftis(p[i])&&l.rightis(p[(i+1)%siz(p)])){
				b.push_back(focus(l,segment(p[i],p[(i-1+siz(p))%siz(p)])));
				b.push_back(p[i]);
				b.push_back(focus(l,segment(p[i],p[(i+1)%siz(p)])));
			}else if(l.leftis(p[i])&&l.rightis(p[(i+1)%siz(p)])){
				b.push_back(p[i]);
				b.push_back(focus(l,segment(p[i],p[(i+1)%siz(p)])));
			}else if(l.leftis(p[i])&&l.rightis(p[(i-1+siz(p))%siz(p)])){
				b.push_back(focus(l,segment(p[i],p[(i-1+siz(p))%siz(p)])));
				b.push_back(p[i]);
			}else if(l.leftis(p[i]))b.push_back(p[i]);
		}
		// for(auto it:b)cout<<it<<'\n';
		// cout<<"===============\n";
		return b;
	}
#undef p
};
circle mingenshin(points b){
	shuffle(all(b),rng);
	circle ans;
	for(int i=0;i<siz(b);i++)if(!ans.check(b[i])){
		ans={b[i],0};
		for(int j=0;j<i;j++)if(!ans.check(b[j])){
			ans=circle(b[i],b[j]);
			for(int k=0;k<j;k++)if(!ans.check(b[k])){
				ans=circle(b[i],b[j],b[k]);
			}
		}
	}
	return ans;
}
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	std::ios::sync_with_stdio(false);cin.tie(nullptr);
	cout<<setiosflags(ios::fixed)<<setprecision(10);
	points a;
	a.read(cin);
	cout<<a.kqzx();
	return 0;
}
accuracy: 1
time_ms: 60
memory_kb: 7740
final_rank: 4

code_snippet: #include<iostream>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<vector>

using namespace std;

struct point
{
    double x, y;
};

bool cmp_x(const point& a, const point& b)
{
    if(a.x != b.x) return a.x < b.x;
    else return a.y < b.y;
}

bool cmp_y(const point& a, const point& b)
{
    if(a.y != b.y) return a.y < b.y;
    else return a.x < b.x;
}

double dist(point& a, point& b)
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double dnc(vector<point>& half_space, vector<point>& half_space_y)
{
    double min_dist = 1e9;
    point mid;
    vector<point> left, left_y, right, right_y, merge_y;

    if(half_space.size() < 2) return 1e9;

    mid = half_space[half_space.size() >> 1];
    for(int i = 0; i < half_space.size(); ++i)
    {
        if(half_space[i].x < mid.x) left.push_back(half_space[i]);
        else right.push_back(half_space[i]);
        if(half_space_y[i].x < mid.x) left_y.push_back(half_space_y[i]);
        else right_y.push_back(half_space_y[i]);
    }
    if(!left.empty()) min_dist = min(dnc(left, left_y), dnc(right, right_y));

    for(int i = 0; i < half_space_y.size(); ++i) if(fabs(half_space_y[i].x - mid.x) <= min_dist) merge_y.push_back(half_space_y[i]);
    for(int i = 0; i < merge_y.size(); ++i)
    {
        for(int j = i + 1; j < merge_y.size(); ++j)
        {
            if(merge_y[j].y - merge_y[i].y > min_dist) break;
            min_dist = min(min_dist, dist(merge_y[i], merge_y[j]));
        }
    }
    return min_dist;
}

int main()
{
    int n;
    vector<point> space, space_y;
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        point now;
        cin >> now.x >> now.y;
        space.push_back(now);
        space_y.push_back(now);
    }
    sort(space.begin(), space.end(), cmp_x);
    sort(space_y.begin(), space_y.end(), cmp_y);
    cout << fixed << setprecision(7) << dnc(space, space_y) << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 13396
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;

namespace DBG
{
    template <class T>
    void _dbg(const char *f, T t) { cerr << f << '=' << t << '\n'; }
    template <class A, class... B>
    void _dbg(const char *f, A a, B... b)
    {
        while (*f != ',')
            cerr << *f++;
        cerr << '=' << a << ",";
        _dbg(f + 1, b...);
    }
    template <typename Container>
    void _print(const char *f, const Container &v)
    {
        cerr << f << " = [ ";
        for (const auto &x : v)
            cerr << x << ", ";
        cerr << "]\n";
    }
#define bug(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#define bugv(container) _print(#container, container)
}
using namespace DBG;

void _();
int main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cout << fixed << setprecision(10);
    int T = 1;
    // cin >> T;
    while (T--)
        _();
    return 0;
}

#define int long long

using ld = long double;
const ld eps = 1e-9;
const ld PI = acos(-1);
#define Pt Point<T>
#define Pd Point<ld>
#define Lt Line<T>
#define Ld Line<ld>

int sign(ld x) // 判符号
{
    if (fabsl(x) < eps)
        return 0;
    else
        return x < 0 ? -1 : 1;
}
bool equal(ld x, ld y) { return !sign(x - y); } // 近似
bool big(ld has, ld tar) { return sign(has - tar) > 0; }

////////////////////////////////////////////////////////////////////////////  点类

//  点与向量
template <class T>
struct Point
{
    T x, y;

    Point(T x = 0, T y = 0) : 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*(T k) const { return Point(x * k, y * k); }
    Point operator/(T k) const { return Point(x / k, y / k); }

    friend bool operator<(Point a, Point b)
    {
        if (!equal(a.x, b.x))
            return a.x < b.x;
        return a.y < b.y;
    }
    friend bool operator>(Point a, Point b) { return b < a; }
    friend bool operator==(Point a, Point b) { return equal(a.x, b.x) && equal(a.y, b.y); } // 近似
    friend bool operator!=(Point a, Point b) { return !(a == b); }
    friend auto &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }
    friend auto &operator<<(ostream &os, Point p) { return os << "(" << p.x << ", " << p.y << ")"; }
};

ld len(Point<ld> a) { return sqrtl(a.x * a.x + a.y * a.y); }; // 模长
ld dis(Point<ld> a, Point<ld> b) { return len(a - b); }       // 两点距离

ld cross(Point<ld> a, Point<ld> b) { return a.x * b.y - a.y * b.x; } // 叉积 ab*sin 两点与原点三角形面积  判两点位置关系两侧
ld cross(Point<ld> p0, Point<ld> p1, Point<ld> p2) { return cross(p1 - p0, p2 - p0); }
ld dot(Point<ld> a, Point<ld> b) { return a.x * b.x + a.y * b.y; } // 点积 ab*cos  结合判两点象限位置关系
ld dot(Point<ld> p0, Point<ld> p1, Point<ld> p2) { return dot(p1 - p0, p2 - p0); }
ld angle(Point<ld> a, Point<ld> b) { return atan2(cross(a, b), dot(a, b)); } // 向量夹角[-pi, pi]  非负fabsl

Point<ld> standardize(Point<ld> h) // 转换为单位向量
{
    ld l = len(h);
    if (sign(l) == 0)
        return {0, 0}; // 防止除零
    return h / l;
}
Pd rotate(Pd p, ld rad) { return {p.x * cos(rad) - p.y * sin(rad), p.x * sin(rad) + p.y * cos(rad)}; } // 向量旋转任意角度

Pd rotate90(Pd a) { return Point<ld>{-a.y, a.x}; }                                   // 旋转90° 垂直向量
ld toDeg(ld x) { return x * 180 / PI; }                                              // 弧度转角度
ld toArc(ld x) { return PI / 180 * x; }                                              // 角度转弧度
ld angle(ld a, ld b, ld c) { return acos((a * a + b * b - c * c) / (2.0 * a * b)); } // 余弦定理 三边求角C弧度

////////////////////////////////////////////////////////////////////////  直线与线段

// 直线
template <class T>
struct Line
{
    Point<T> a, b;
    Line(Pt a_ = {}, Pt b_ = {}) : a(a_), b(b_) {}
    friend auto &operator<<(ostream &os, Line l) { return os << "<" << l.a << ", " << l.b << ">"; }
};
bool pointOnLineLeft(Pd p, Ld l) { return cross(l.b - l.a, p - l.a) > 0; } // 点在直线左侧
bool onLine(Pd a, Pd b, Pd c) { return sign(cross(a - b, c - b)) == 0; }   // 点是否在直线上（三点是否共线）ok
bool onLine(Pd p, Ld l) { return onLine(p, l.a, l.b); }
// 线段：点是否在线段上 ok
bool pointOnSegment(Pd p, Ld l) { return fabsl(cross(l.a - p, l.b - p)) < eps && dot(l.a - p, l.b - p) <= 0; }
bool Parallel(Pd p1, Pd p2) { return equal(0, cross(p1, p2)); }                          // 平行 ok
bool Orthogonal(Pd p1, Pd p2) { return equal(0, dot(p1, p2)); }                          // 垂直 ok
Ld midSegment(Ld l) { return {(l.a + l.b) / 2, (l.a + l.b) / 2 + rotate90(l.a - l.b)}; } // 线段的中垂线

ld disPointToLine(Pd p, Ld l, bool isSegment = false) // 点到直线/线段的最近距离 ok
{
    ld len_ab = dis(l.a, l.b);
    if (sign(len_ab) == 0)
        return dis(p, l.a);
    if (!isSegment)
    {
        ld ans = cross(p, l.a, l.b);
        return fabsl(ans) / dis(l.a, l.b); // 面积除以底边长
    }
    else
    {
        if (dot(p - l.a, l.b - l.a) <= 0)
            return dis(p, l.a);
        if (dot(p - l.b, l.a - l.b) <= 0)
            return dis(p, l.b);
        ld ans = cross(p, l.a, l.b);
        return fabsl(ans) / dis(l.a, l.b);
    }
}

Pd lineIntersection(Ld l1, Ld l2, bool seg1 = false, bool seg2 = false) // 两直线/线段相交交点 ok
{
    ld det = cross(l1.b - l1.a, l2.b - l2.a);
    if (sign(det) == 0) // 1. 平行或共线
    {
        if (sign(cross(l2.a - l1.a, l1.b - l1.a)) != 0) // 如果不共线 -> 平行
            return Pd(1e18, 1e18);

        if (pointOnSegment(l1.a, l2)) // 共线情况：检查端点是否重合/相连
            return l1.a;
        if (pointOnSegment(l1.b, l2))
            return l1.b;
        if (pointOnSegment(l2.a, l1))
            return l2.a;
        if (pointOnSegment(l2.b, l1))
            return l2.b;
        return Pd(1e18, 1e18); // 完全不相交
    }

    ld t = cross(l2.a - l1.a, l2.b - l2.a) / det; // 2. 一般情况，唯一交点 ✅
    Pd inter = l1.a + (l1.b - l1.a) * t;

    if ((seg1 && !pointOnSegment(inter, l1)) || (seg2 && !pointOnSegment(inter, l2)))
        return Pd(1e18, 1e18); // 不在线段上

    return inter;
}

Pd project(Pd p, Ld l, bool isSegment = false) // 点在直线/线段上的投影点（垂足）ok
{
    Pd h = l.b - l.a;
    ld r = dot(h, p - l.a) / (h.x * h.x + h.y * h.y);
    Pd pro = l.a + h * r;
    if (isSegment)
    {
        if (dot(pro - l.a, l.b - l.a) < 0)
            return l.a;
        if (dot(pro - l.b, l.a - l.b) < 0)
            return l.b;
    }
    return pro;
}

// /////////////////////////////////////////////////////////////////////////////////////////   多边形

using Polygon = vector<Point<ld>>;
ld area(vector<Pd> P) // 任意多边形的面积 ok
{
    int n = P.size();
    ld ans = 0;
    for (int i = 0; i < n; i++)
    {
        ans += cross(P[i], P[(i + 1) % n]);
    }
    return ans / 2.0;
}
int contains(Polygon g, Point<ld> p) // 点与多边形位置关系 内2 上1 外0 ok
{
    int n = g.size();
    bool x = false;
    for (int i = 0; i < n; i++)
    {
        Point<ld> a = g[i] - p, b = g[(i + 1) % n] - p;
        if (abs(cross(a, b)) < eps && dot(a, b) < eps)
            return 1;
        if (a.y > b.y)
            swap(a, b);
        if (a.y < eps && eps < b.y && cross(a, b) > eps)
            x = !x;
    }
    return (x ? 2 : 0);
}
bool isConvexHull(Polygon p) // 是否为凸包 ok
{
    int n = p.size();
    int same[2] = {};
    for (int i = 0; i < n; i++)
    {
        int l = (i + n - 1) % n, r = (i + 1) % n;
        if (sign(cross(p[l] - p[i], p[r] - p[i])) <= 0)
            same[0] = 1;
        else
            same[1] = 1;
    }
    return same[0] + same[1] < 2;
}

Polygon getHull(Polygon p) // 点集求凸包 <=不选共线点 <选共线点 ok
{
    Polygon h, l;
    sort(p.begin(), p.end());
    p.erase(unique(p.begin(), p.end()), p.end());
    if (p.size() <= 1)
        return p;
    for (auto a : p)
    {
        while (h.size() > 1 && cross(a - h.back(), a - h[h.size() - 2]) <= 0) //
            h.pop_back();
        while (l.size() > 1 && cross(a - l.back(), a - l[l.size() - 2]) >= 0) //
            l.pop_back();
        l.push_back(a);
        h.push_back(a);
    }
    l.pop_back();
    reverse(h.begin(), h.end());
    h.pop_back();
    l.insert(l.end(), h.begin(), h.end());
    return l;
}

Polygon sortConvexHullCCW(Polygon h) // 将凸包点集按逆时针排序，从y最小（y相同则x最小）的点开始 ok
{
    int pos = 0;
    for (int i = 0; i < h.size(); i++)
    {
        if (h[i].y < h[pos].y)
            pos = i;
        else if (h[i].y == h[pos].y)
        {
            if (h[i].x < h[pos].x)
                pos = i;
        }
    }
    rotate(h.begin(), h.begin() + pos, h.end());
    return h;
}

ld diameter(Polygon h) // 旋转卡壳求凸包直径 ok
{
    auto poly = h;
    if (poly.size() == 1)
        return 0;
    if (poly.size() == 2)
        return len(poly[1] - poly[0]);
    if (poly.size() == 3)
        return max({len(poly[1] - poly[0]), len(poly[2] - poly[1]), len(poly[0] - poly[2])});

    size_t cur = 0;
    ld ans = 0;
    for (size_t i = 0; i < poly.size(); i++)
    {
        size_t j = (i + 1) % poly.size();
        Line<ld> line(poly[i], poly[j]);
        while (disPointToLine(poly[cur], line) <= disPointToLine(poly[(cur + 1) % poly.size()], line))
        {
            cur = (cur + 1) % poly.size();
        }
        ans = max(ans, max(len(poly[i] - poly[cur]), len(poly[j] - poly[cur])));
    }
    return ans;
}

ld ClosestPair(vector<Pd> &p, int l, int r) // 最近点对 先排序
{
    if (l == r)
        return 1e18;
    if (l + 1 == r)
        return dis(p[l], p[r]);
    int mid = l + r >> 1;
    ld ans = min(ClosestPair(p, l, mid), ClosestPair(p, mid + 1, r));

    vector<Pd> b;
    for (int i = l; i <= r; i++)
        if (fabsl(p[i].x - p[mid].x) < ans)
            b.push_back(p[i]);

    sort(b.begin(), b.end(), [](Pd &e1, Pd &e2)
         { return e1.y <= e2.y; });
    int m = b.size();
    for (int i = 0; i < m; i++)
        for (int j = i + 1; j < m && dis(b[i], b[j]) < ans; j++)
            ans = min(ans, dis(b[i], b[j]));
    return ans;
}
void _()
{
    int n;
    cin >> n;

    vector<Pd> p(n);
    for (auto &v : p)
        cin >> v;

    sort(p.begin(), p.end());
    ld ans = ClosestPair(p, 0, n - 1);
    cout << ans << '\n';
}
accuracy: 1
time_ms: 70
memory_kb: 12284
final_rank: 13

code_snippet: #include<iostream>
#include<iomanip>
#include<cmath>
#include<algorithm>
#include<vector>

using namespace std;

struct point
{
    double x, y;
};

bool cmp_x(const point& a, const point& b)
{
    if(a.x != b.x) return a.x < b.x;
    else return a.y < b.y;
}

bool cmp_y(const point& a, const point& b)
{
    if(a.y != b.y) return a.y < b.y;
    else return a.x < b.x;
}

double dist(point& a, point& b)
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

double dnc(vector<point>& half_space, vector<point>& half_space_y)
{
    double min_dist = 1e9;
    point mid;
    vector<point> left, left_y, right, right_y, merge_y;

    if(half_space.size() < 2) return 1e9;

    mid = half_space[half_space.size() >> 1];
    for(int i = 0; i < half_space.size(); ++i)
    {
        if(half_space[i].x < mid.x) left.push_back(half_space[i]);
        else right.push_back(half_space[i]);
        if(half_space_y[i].x < mid.x) left_y.push_back(half_space_y[i]);
        else right_y.push_back(half_space_y[i]);
    }
    if(!left.empty()) min_dist = min(dnc(left, left_y), dnc(right, right_y));

    for(int i = 0; i < half_space_y.size(); ++i) if(fabs(half_space_y[i].x - mid.x) <= min_dist) merge_y.push_back(half_space_y[i]);
    for(int i = 0; i < merge_y.size(); ++i)
    {
        for(int j = i + 1; j < merge_y.size(); ++j)
        {
            if(merge_y[j].y - merge_y[i].y > min_dist) break;
            min_dist = min(min_dist, dist(merge_y[i], merge_y[j]));
        }
    }
    return min_dist;
}

int main()
{
    int n;
    vector<point> space, space_y;
    cin >> n;
    for(int i = 0; i < n; ++i)
    {
        point now;
        cin >> now.x >> now.y;
        space.push_back(now);
        space_y.push_back(now);
    }
    sort(space.begin(), space.end(), cmp_x);
    sort(space_y.begin(), space_y.end(), cmp_y);
    cout << fixed << setprecision(7) << dnc(space, space_y) << endl;
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 13356
final_rank: 16