Problem:
問題 ４

　平面上の n 個の点 P1, ..., Pn が与えられたとき，
距離が最小の２点を求めたい．

　入力ファイルの１行目には整数 n が書いてある．
２行目から n+1 行目のそれぞれには，
２つの正整数 x, y が１つの半角空白文字を区切りとして書いてある．
i+1 行目の x, y はそれぞれ Pi の x 座標，
Pi の y 座標である．
これら n 点の中から最も近い２点を選んだとき，
この２点間の距離の２乗を出力せよ．

　ただし，
2≤n≤500000 かつ -10000≤x≤10000, -10000≤y≤10000 とし，
５つの入力ファイルのうち３つでは n≤100 である．
また，どの入力ファイルにおいても，全ての座標は異なるものとする．

出力ファイルにおいては，
出力の最後の行にも改行コードを入れること．

入出力例

入力例１

2
0 0
1 1

出力例１

2

入力例２

3
5 5
0 0
-3 -4

出力例２

25

問題文と自動審判に使われるデータは、情報オリンピック日本委員会が作成し公開している問題文と採点用テストデータです。

Solution in Ruby (judge verdict: Memory Limit Exceeded)

include Math
W = 20000
B = 80
n = gets.to_i

blocks = Array.new(W/B+1)
points = []
min_d = Float::INFINITY
min_d2 = 0
x0, y0 = 10*W, 10*W

n.times{|point_idx|
	x, y = gets.split.map(&:to_i)
	x += 10000
	y += 10000

	d = sqrt( (x-x0)**2 + (y-y0)**2 )
	if d < min_d
		min_d = d
		min_d2 = (x-x0)**2 + (y-y0)**2
	end

	x0, y0 = x, y

	blocks[y/B] ||= Array.new(W/B+1)
	(blocks[y/B][x/B] ||= []) << point_idx
	points << [x, y]
}

(0..n-1).each{|idx0|
	x0, y0 = points[idx0]
	i0, j0 = y0/B, x0/B
	for i in [i0-(min_d/B).ceil, 0].max..[i0+(min_d/B).ceil,blocks.size-1].min
		dy = ((i-i0).abs-1) * B

		for j in [j0-(min_d/B).ceil, 0].max..[j0+(min_d/B).ceil,blocks.size-1].min
			next unless blocks[i]
			next unless blocks[i][j]
			dx = ((j-j0).abs-1) * B
			next if dx > 0 && dx*dx + dy*dy > min_d**2

			blocks[i][j].each{|idx1|
				x1, y1 = points[idx1]
				next if idx0 >= idx1
				d = sqrt( (x1-x0)**2 + (y1-y0)**2 )
				if d < min_d
					min_d = d
					min_d2 = (x1-x0)**2 + (y1-y0)**2
				end
			}
		end
	end
}

p min_d2