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 C (judge verdict: Wrong Answer)

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct {
	int x, y;
} zahyo_t;

int n;
zahyo_t zahyo[500000];
int init[500000];

#ifndef BUILD_CASE_GENERATOR
int direct_solve(const int* data, int num) {
	int i, j;
	int ret = -1;
	for (i = 0; i < num; i++) {
		for (j = i + 1; j < num; j++) {
			int score = (zahyo[data[i]].x - zahyo[data[j]].x) * (zahyo[data[i]].x - zahyo[data[j]].x) +
				(zahyo[data[i]].y - zahyo[data[j]].y) * (zahyo[data[i]].y - zahyo[data[j]].y);
			if (ret < 0 || score < ret) ret = score;
		}
	}
	return ret;
}

int search(const int* data, int num, int limit) {
	int next_data_num[4];
	int* next_data[4];
	if (num <= 100) {
		return direct_solve(data, num);
	} else {
		int i;
		int minx = zahyo[data[0]].x, miny = zahyo[data[0]].y;
		int maxx = zahyo[data[0]].x, maxy = zahyo[data[0]].y;
		int mx, my;
		int ret = -1;
		for (i = 1; i < num; i++) {
			int x = zahyo[data[i]].x, y = zahyo[data[i]].y;
			if (x < minx) minx = x;
			if (x > maxx) maxx = x;
			if (y < miny) miny = y;
			if (y > maxy) maxy = y;
		}
		mx = minx + (maxx - minx) / 2;
		my = miny + (maxy - miny) / 2;
		if (limit >= 0) {
			if (mx - minx < limit || maxx - mx < limit || my - miny < limit || maxy - my < limit) {
				return direct_solve(data, num);
			}
		}
		for (i = 0; i < 4; i++) {
			next_data[i] = malloc(sizeof(int) * num);
			if (next_data[i] == NULL) exit(1);
			next_data_num[i] = 0;
		}
		for (i = 0; i < num; i++) {
			int x = zahyo[data[i]].x, y = zahyo[data[i]].y;
			if (x <= mx && y <= my) next_data[0][next_data_num[0]++] = data[i];
			if (mx < x && y <= my) next_data[1][next_data_num[1]++] = data[i];
			if (x <= mx && my < y) next_data[2][next_data_num[2]++] = data[i];
			if (mx < x && my < y) next_data[3][next_data_num[3]++] = data[i];
		}
		for (i = 0; i < 4; i++) {
			int candidate = search(next_data[i], next_data_num[i], limit);
			if (candidate >= 0 && (ret < 0 || candidate < ret)) ret = candidate;
			free(next_data[i]);
		}
		return ret;
	}
}

int main(void) {
	int i;
	if (scanf("%d", &n) != 1) return 1;
	for (i = 0; i < n; i++) {
		if (scanf("%d%d", &zahyo[i].x, &zahyo[i].y) != 2) return 1;
		init[i] = i;
	}
	printf("%d\n", search(init, n, (int)(sqrt(search(init, n, -1)) + 1.1)));
	return 0;
}
#else
#include <time.h>

int main(int argc, char* argv[]) {
	int num = argc >= 2 ? atoi(argv[1]) : 1000;
	int i, j;
	int minDist = -1;
	time_t prevTime = time(NULL);
	srand((unsigned int)prevTime);
	for (i = 0; i < num; i++) {
		int tempMinDist = -1;
		time_t curTime = time(NULL);
		if (curTime != prevTime) {
			fprintf(stderr, "generating... %d / %d\n", i, num);
			prevTime = curTime;
		}
		zahyo[i].x = rand() % 20001 - 10000;
		zahyo[i].y = rand() % 20001 - 10000;
		for (j = 0; j < i; j++) {
			int dist = (zahyo[i].x - zahyo[j].x) * (zahyo[i].x - zahyo[j].x) +
				(zahyo[i].y - zahyo[j].y) * (zahyo[i].y - zahyo[j].y);
			if (dist == 0) {
				i--;
				j = -1;
				break;
			} else {
				if (tempMinDist < 0 || dist < tempMinDist) tempMinDist = dist;
			}
		}
		if (j >= 0 && (minDist < 0 || tempMinDist < minDist)) minDist = tempMinDist;
	}
	fprintf(stderr, "answer = %d\n", minDist);
	printf("%d\n", i);
	for (i = 0; i < num; i++) {
		printf("%d %d\n", zahyo[i].x, zahyo[i].y);
	}
	return 0;
}
#endif