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 JAVA (judge verdict: Time Limit Exceeded)

import java.awt.Point;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Map;
import java.util.Queue;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;

public class Main {
	
	public static int min_dist_2(final int n, final int start, final Point[] points){
		if(n <= 1){
			return Integer.MAX_VALUE;
		}
		
		final int m = n / 2;
		
		int d = Math.min(min_dist_2(m, start, points), min_dist_2(n - m, start + m, points));
		System.gc();
		LinkedList<Point> list = new LinkedList<Point>();
		final int x = points[start].x;
		for(int i = 0; i < n; i++){
			final int pos = start + i;
			
			final int tmp_d = (points[pos].x - x) * (points[pos].x - x);
			if(tmp_d >= d){
				continue;
			}
			
			for(Point another : list){
				final int dx = points[pos].x - another.x;
				final int dy = points[pos].y - another.y;
				/*
				if(dy > 0 && dy * dy >= d){
					break;
				}
				*/
				d = Math.min(d, dx * dx + dy * dy);
			}
			
			list.add(points[pos]);
		}
		
		return d;
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		final int n = sc.nextInt();
		
		Point[] points = new Point[n];
		
		for(int i = 0; i < n; i++){
			points[i] = new Point(sc.nextInt(), sc.nextInt());
		}
		
		Arrays.sort(points, new Comparator<Point>() {
			@Override
			public int compare(Point o1, Point o2) {
				if(o1.x != o2.x){
					return o1.x - o2.x;
				}else{
					return o1.y - o2.y;
				}
			}
		});
		
		System.out.println(min_dist_2(n, 0, points));
	}

}