Problem:
Closest Pair

For given n points in metric space, find the distance of the closest points.

Input

n
x0 y0
x1 y1
:
xn-1 yn-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 xi and yi. 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

Solution in Kotlin (judge verdict: Time Limit Exceeded)

import java.math.BigDecimal
import java.util.*
import java.io.IOException

internal class FastScanner {
    private val `in` = System.`in`
    private val buffer = ByteArray(1024)
    private var ptr = 0
    private var buflen = 0
    private fun hasNextByte(): Boolean {
        if (ptr < buflen) {
            return true
        } else {
            ptr = 0
            try {
                buflen = `in`.read(buffer)
            } catch (e: IOException) {
                e.printStackTrace()
            }

            if (buflen <= 0) {
                return false
            }
        }
        return true
    }

    private fun readByte(): Int {
        return if (hasNextByte()) buffer[ptr++].toInt() else -1
    }

    private fun isPrintableChar(c: Int): Boolean {
        return 33 <= c && c <= 126
    }

    operator fun hasNext(): Boolean {
        while (hasNextByte() && !isPrintableChar(buffer[ptr].toInt())) ptr++
        return hasNextByte()
    }

    operator fun next(): String {
        if (!hasNext()) throw NoSuchElementException()
        val sb = StringBuilder()
        var b = readByte()
        while (isPrintableChar(b)) {
            sb.appendCodePoint(b)
            b = readByte()
        }
        return sb.toString()
    }

    fun nextLong(): Long {
        if (!hasNext()) throw NoSuchElementException()
        var n: Long = 0
        var minus = false
        var b = readByte()
        if (b == '-'.toInt()) {
            minus = true
            b = readByte()
        }
        if (b < '0'.toInt() || '9'.toInt() < b) {
            throw NumberFormatException()
        }
        while (true) {
            if ('0'.toInt() <= b && b <= '9'.toInt()) {
                n *= 10
                n += (b - '0'.toInt()).toLong()
            } else return if (b == -1 || !isPrintableChar(b)) {
                if (minus) -n else n
            } else {
                throw NumberFormatException()
            }
            b = readByte()
        }
    }

    fun nextInt(): Int {
        val nl = nextLong()
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw NumberFormatException()
        return nl.toInt()
    }

    fun nextDouble(): Double {
        return java.lang.Double.parseDouble(next())
    }
}
fun solve(a: Array<Array<Double>>, sortedAxis: Int = -1): Double {
    if (a.size <= 3) {
        var dist = 1000000000000.0
        for ((i, p1) in a.withIndex()) {
            for (p2 in a.takeLast(a.size-i-1)) {
                dist = Math.min(dist, Math.sqrt(Math.pow(p1[0]-p2[0], 2.0)+Math.pow(p1[1]-p2[1], 2.0)))
            }
        }
        return dist
    }

    val mid = a.size/2
    val xSetLen = HashSet(a.map { it -> it[0] }).size
    val (axis1, axis2) = if (xSetLen >= mid) Pair(0, 1) else Pair(1, 0)
    if (axis1 != sortedAxis) a.sortBy { it[axis1] }

    val leftArray = a.sliceArray(0 until mid)
    val rightArray = a.sliceArray(mid until a.size)
    var delta = Math.min(
            solve(leftArray, axis1),
            solve(rightArray, axis1)
    )
    val median = a[mid][axis1]
    val mid_a = a.filter { it[axis1] in median-delta..median+delta }.sortedBy { it[axis2] }

    for (i in 0 until mid_a.size-1) {
        val ub = mid_a[i][axis2] + delta
        for (j in i+1 until mid_a.size) {
            if (mid_a[i][axis2] >= ub) break
            delta = Math.min(delta,
                    Math.sqrt(Math.pow(mid_a[i][0]-mid_a[j][0], 2.0)+Math.pow(mid_a[i][1]-mid_a[j][1], 2.0)))
        }
    }

    return delta
}

fun main(args: Array<String>) {
    val sc = FastScanner()
    val N = sc.nextInt()
    val a = Array(N, { arrayOf(sc.nextDouble(), sc.nextDouble()) })
    val ans = solve(a)
    println(BigDecimal.valueOf(ans).toPlainString())
}