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

有理式最大化

N 個の異なる自然数が与えられる。その中から異なる４つを選んで、それらを $A$, $B$, $C$, $D$ としたとき、次の数式

$\frac{A + B}{C - D}$

の最大値を求めたい。

N 個の異なる自然数が与えられたとき、その中から異なる４つを選んで、上の数式の最大値を求めるプログラムを作成せよ。

Input

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

N
a1 a2 ... aN

１行目に自然数の個数 N (4 ≤ N ≤ 1000) が与えられる。２行目に各自然数の値 ai (1 ≤ ai ≤ 108) が与えられる。ただし、同じ自然数が重複して現れることはない（i ≠ j について ai ≠ aj)。

Output

与えられた N 個の自然数に対して、上の数式の最大値を実数で出力する。ただし、誤差がプラスマイナス 10-5 を超えてはならない。

Sample Input 1

10
1 2 3 4 5 6 7 8 9 10

Sample Output 1

19.00000

入力例１では、$A=9$, $B=10$, $C=2$, $D=1$ などの組み合わせで最大になる。

Sample Input 2

5
22 100 42 3 86

Sample Output 2

9.78947

入力例２では、$A=100$, $B=86$, $C=22$, $D=3$ などの組み合わせで最大になる。

Sample Input 3

6
15 21 36 10 34 5

Sample Output 3

18.00000

入力例３では、$A=21$, $B=15$, $C=36$, $D=34$ などの組み合わせで最大になる。

Sample Input 4

4
100000 99999 8 1

Sample Output 4

28571.285714

Solution in C (judge verdict: Accepted)

// Aizu Vol-3 0347: Maximization of Relational Expression
// 2017.8.27 bal4u@uu

#include <stdio.h>

#define MAX 1000
#define abs(a) ((a)>=0?(a):-(a))
typedef struct { int i, j, v; } T;
T max[MAX+3], min[MAX+3]; int nmax, nmin;
int a[MAX+3], N;

void first_nmax(int v, int i, int j)
{
	int ii, jj;

	for (ii = 0; ii < nmax; ii++) {
		if (v <= max[ii].v) continue;
		for (jj = nmax-1; jj >= ii; jj--) max[jj+1] = max[jj];
		if (nmax < N) nmax++;
		max[ii].i = i, max[ii].j = j, max[ii].v = v;
		return;
	}
	if (ii == nmax && nmax < N)	max[ii].i = i, max[ii].j = j, max[ii].v = v, nmax++;
}

void first_nmin(int v, int i, int j)
{
	int ii, jj;

	for (ii = 0; ii < nmin; ii++) {
		if (v >= min[ii].v) continue;
		for (jj = nmin-1; jj >= ii; jj--) min[jj+1] = min[jj];
		if (nmin < N) nmin++;
		min[ii].i = i, min[ii].j = j, min[ii].v = v;
		return;
	}
	if (ii == nmin && nmin < N)	min[ii].i = i, min[ii].j = j, min[ii].v = v, nmin++;
}

int main()
{
    int i, j;
    double x, y;

	//memset(max, 0, sizeof(max)), memset(min, 0, sizeof(min));
    scanf("%d", &N);
    for (i = 0; i < N; i++) scanf("%d", a + i);
	max[0].i = min[0].i, max[0].j = min[0].j = 1,
    max[0].v = a[0] + a[1], min[0].v = abs(a[0] - a[1]), nmax = nmin = 1;
    for (i = 2; i < N; i++) for (j = 0; j < i; j++) first_nmax(a[i] + a[j], i, j);
    for (i = 2; i < N; i++) for (j = 0; j < i; j++) first_nmin(abs(a[i] - a[j]), i, j);
    for (i = 0; i < N; i++) {
        if ((min[i].i != max[0].i && min[i].j != max[0].i) &&
            (min[i].i != max[0].j && min[i].j != max[0].j)) break;
	}
	x = (double)max[0].v / (double)min[i].v, x = abs(x);
	for (i = 0; i < N; i++) {
		if ((max[i].i != min[0].i && max[i].j != min[0].i) &&
            (max[i].i != min[0].j && max[i].j != min[0].j)) break;
	}
    y = (double)max[i].v / (double)min[0].v; y = abs(y);
	printf("%.8lf\n", x >= y ? x : y);
    return 0;
}