Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

ヒバラ海に沈む遺跡

アイヅ考古学会は、ヒバラ海に沈む古代国家イワシロの遺跡調査に乗り出した。遺跡はヒバラ海のどこか一か所に存在する。そこで、探査レーダを使い、海岸線からのレーダ探査で遺跡の位置のおおよその目星を付け、海岸線から最大何メートル離れた位置まで調査しなければならないかを見積もることにした。

上図のような直線で表された海岸線上に観測点を設置し、探査レーダを置く。探査レーダでは、観測点を中心とする、ある大きさの半円の範囲に遺跡があるということしかわからない。しかし、複数の観測データを組み合わせることで、より狭い範囲に絞り込むことができる。

観測点の位置と探査レーダが示す半径からなるいくつかの観測データが与えられたとき、海岸線から最大でどのくらいの距離まで調査する必要があるかを求めるプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

N
x1 r1
x2 r2
:
xN rN

１行目に探査レーダによって測定されたデータの数 N (1 ≤ N ≤ 100000) が与えられる。続く N 行に、観測データ i の海岸線上での位置をメートル単位で表す整数 xi (0 ≤ xi ≤ 1,000,000) と、その位置から半径何メートル以内に遺跡が存在するかを表す整数 ri (1 ≤ ri ≤ 1,000,000) が与えられる。観測点が同じ観測データが２つ以上与えられることもある。

与えられた観測データが複数の場合、それらすべての半円に含まれる点が必ず存在すると考えてよい。

Output

海岸線から最大で何メートルまで調査する必要があるかを実数で出力する。ただし、誤差がプラスマイナス 0.001 メートルを超えてはならない。この条件を満たせば小数点以下は何桁表示してもよい。

Sample Input 1

2
0 2
1 2

Sample Output 1

1.936

Sample Input 2

3
0 3
1 2
2 1

Sample Output 2

1.0

Sample Input 3

2
0 1
3 2

Sample Output 3

0.0

Solution in C (judge verdict: Accepted)

// AOJ 323 ruins
// 2018.2.25 bal4u

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

#define LIM		30
#define MAX		1000002
#define EPS		1e-8
 
typedef struct { int x, r; long long r2; } T;
T tbl[100002];
int n;

//#define getchar_unlocked()  getchar()
int in()
{
	int n = 0;
	int c = getchar_unlocked();
	do n = (n<<3)+(n<<1) + (c & 0xf), c = getchar_unlocked();
	while (c >= '0');
	return n;
}

int check(double d)
{
	int i;
	double xmin, xmax, xx, d2;

	d2 = d*d;
	xmin = -MAX, xmax = MAX;
	for (i = 0; i < n; i++) {
		if (tbl[i].r < d) return 0;
		xx = sqrt(tbl[i].r2 - d2);
		if (tbl[i].x - xx > xmin) xmin = tbl[i].x - xx;
		if (tbl[i].x + xx < xmax) xmax = tbl[i].x + xx;
		if (xmin > xmax) return 0;
	}
	return 1;
}

int cmp(T *a, T *b) { if (a->r - b->r) return a->r - b->r; return a->x - b->x; }

int main()
{
	int i;
	double hi, lo, mi;

	n = in();
	for (i = 0; i < n; i++) {
		tbl[i].x = in(), tbl[i].r = in();
		tbl[i].r2 = (long long)tbl[i].r * tbl[i].r;
	}
	if (i == 1) { printf("%.6lf\n", (double)tbl[0].r); return 0; }

	qsort(tbl, n, sizeof(T), cmp);
	lo = 0, hi = MAX;
	for (i = 0; i < LIM; i++) {
		mi = 0.5*(lo + hi);
		if (check(mi)) lo = mi; else hi = mi;
	}
	printf("%.6lf\n", lo);
	return 0;
}