Problem:
Problem C:
Tetrahedra
Peter P. Pepper is facing a difficulty.
After fierce battles with the Principality of Croode, the Aaronbarc Kingdom, for which he serves, had
the last laugh in the end. Peter had done great service in the war, and the king decided to give him a
big reward. But alas, the mean king gave him a hard question to try his intelligence. Peter is given a
number of sticks, and he is requested to form a tetrahedral vessel with these sticks. Then he will be, said
the king, given as much patas (currency in this kingdom) as the volume of the vessel. In the situation,
he has only to form a frame of a vessel.
Figure 1: An example tetrahedron vessel
The king posed two rules to him in forming a vessel: (1) he need not use all of the given sticks, and (2)
he must not glue two or more sticks together in order to make a longer stick.
Needless to say, he wants to obtain as much patas as possible. Thus he wants to know the maximum
patas he can be given. So he called you, a friend of him, and asked to write a program to solve the
problem.
Input
The input consists of multiple test cases. Each test case is given in a line in the format below:
N a
1
a
2
. . . a
N
where
N
indicates the number of sticks Peter is given, and
a
i
indicates the length (in centimeters) of
each stick. You may assume 6 ≤
N
≤ 15 and 1 ≤
a
i
≤ 100.
The input terminates with the line containing a single zero.
Output
For each test case, print the maximum possible volume (in cubic centimeters) of a tetrahedral vessel
which can be formed with the given sticks. You may print an arbitrary number of digits after the decimal
point, provided that the printed value does not contain an error greater than 10
-6
.
It is guaranteed that for each test case, at least one tetrahedral vessel can be formed.
Sample Input
7 1 2 2 2 2 2 2
0
Output for the Sample Input
0.942809

Submitted solutions:

code_snippet: #include "bits/stdc++.h"

using namespace std;

int s[3];

bool f1(int a, int b, int c) {
    s[0] = a, s[1] = b, s[2] = c;
    sort(s, s + 3);
    return s[0] + s[1] > s[2];
}

double f2(double l1, double l2, double l3, double l4, double l5, double l6) {
    double X = (l6 - l1 + l5) * (l1 + l5 + l6);
    double x = (l1 - l5 + l6) * (l5 - l6 + l1);
    double Y = (l4 - l2 + l6) * (l2 + l6 + l4);
    double y = (l2 - l6 + l4) * (l6 - l4 + l2);
    double Z = (l5 - l3 + l4) * (l3 + l4 + l5);
    double z = (l3 - l4 + l5) * (l4 - l5 + l3);
    double a = sqrt(x * Y * Z);
    double b = sqrt(y * Z * X);
    double c = sqrt(z * X * Y);
    double d = sqrt(x * y * z);
    return sqrt((-a + b + c + d) * (a - b + c + d) * (a + b - c + d) * (a + b + c - d)) / (192 * l4 * l5 * l6);
}

int A[15], p[15], q[6];

signed main() {
    int n;
    while (cin >> n) {
        if (!n) break;
        double ans = 0;
        for (int i = 0; i < n; i++) cin >> A[i];
        for (int i = 0; i < 6; i++) p[i] = 1;
        for (int i = 6; i < 15; i++) p[i] = 0;
        do {
            int it = 0;
            for (int i = 0; i < n; i++) if (p[i] == 1) q[it++] = i;
            do {
                int a = A[q[0]];
                int b = A[q[1]];
                int c = A[q[2]];
                int d = A[q[3]];
                int e = A[q[4]];
                int f = A[q[5]];
                if (f1(a, b, c) && f1(a, e, f) && f1(b, f, d) && f1(c, d, e))
                    ans = max(ans, f2(a, b, c, d, e, f));
            } while (next_permutation(q, q + 6));
        } while (prev_permutation(p, p + n));
        cout << setprecision(6) << fixed << ans << '\n';
    }
}
accuracy: 1
time_ms: 2970
memory_kb: 3516
final_rank: 12

code_snippet: #include "bits/stdc++.h"

using namespace std;

int s[3];

bool f1(int a, int b, int c) {
    s[0] = a, s[1] = b, s[2] = c;
    sort(s, s + 3);
    return s[0] + s[1] > s[2];
}

double f2(double l1, double l2, double l3, double l4, double l5, double l6) {
    double X = (l6 - l1 + l5) * (l1 + l5 + l6);
    double x = (l1 - l5 + l6) * (l5 - l6 + l1);
    double Y = (l4 - l2 + l6) * (l2 + l6 + l4);
    double y = (l2 - l6 + l4) * (l6 - l4 + l2);
    double Z = (l5 - l3 + l4) * (l3 + l4 + l5);
    double z = (l3 - l4 + l5) * (l4 - l5 + l3);
    double a = sqrt(x * Y * Z);
    double b = sqrt(y * Z * X);
    double c = sqrt(z * X * Y);
    double d = sqrt(x * y * z);
    return sqrt((-a + b + c + d) * (a - b + c + d) * (a + b - c + d) * (a + b + c - d)) / (192 * l4 * l5 * l6);
}

int A[15], p[15], q[6];

signed main() {
    int n;
    while (cin >> n) {
        if (!n) break;
        double ans = 0;
        for (int i = 0; i < n; i++) cin >> A[i];
        for (int i = 0; i < 6; i++) p[i] = 1;
        for (int i = 6; i < 15; i++) p[i] = 0;
        do {
            int it = 0;
            for (int i = 0; i < n; i++) if (p[i] == 1) q[it++] = i;
            do {
                int a = A[q[0]];
                int b = A[q[1]];
                int c = A[q[2]];
                int d = A[q[3]];
                int e = A[q[4]];
                int f = A[q[5]];
                if (f1(a, b, c) && f1(a, e, f) && f1(b, f, d) && f1(c, d, e))
                    ans = max(ans, f2(a, b, c, d, e, f));
            } while (next_permutation(q, q + 5));
        } while (prev_permutation(p, p + n));
        cout << setprecision(6) << fixed << ans << '\n';
    }
}
accuracy: 1
time_ms: 480
memory_kb: 3596
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;

#define all(x) (x).begin(), (x).end()

bool tri(int a, int b, int c) {
	vector<int> v = { a, b, c };
	sort(all(v));
	return v[0] + v[1] > v[2];
}

double vol(int U, int V, int W, int u, int v, int w) {
	double X = (w - U + v) * (U + v + w),
		Y = (u - V + w) * (V + w + u),
		Z = (v - W + u) * (W + u + v);
	double x = (U - v + w) * (v - w + U),
		y = (V - w + u) * (w - u + V),
		z = (W - u + v) * (u - v + W);
	double k = sqrt(x * Y * Z),
		e = sqrt(y * Z * X),
		t = sqrt(z * X * Y),
		l = sqrt(x * y * z);
	return sqrt((k + e + t - l) * (l + k + e - t) * (e + t + l - k) * (t + l + k - e)) / (192 * u * v * w);
}

int main() {
	cin.tie(0);
	ios_base::sync_with_stdio(0);

	while (true) {
		int n; cin >> n;
		if (!n) break;
		vector<int> a(n);
		for (auto& i : a) cin >> i;

		vector<bool> p(n);
		fill(p.begin(), p.begin() + 6, true);
		double ans = .0;
		do {
			vector<int> q;
			int c = 0;
			for (int i = 0; i < n; i++) {
				if (p[i]) q.push_back(i);
			}
			do {
				int U = a[q[0]], V = a[q[1]], W = a[q[2]];
				int u = a[q[3]], v = a[q[4]], w = a[q[5]];
				if (tri(U, V, W) && tri(u, v, W) && tri(v, w, U) && tri(w, u, V)) {
					ans = max(ans, vol(U, V, W, u, v, w));
				}
			} while (next_permutation(all(q) - 1));
		} while (prev_permutation(all(p)));
		cout << fixed << setprecision(10) << ans << '\n';
	}
	return 0;
}
accuracy: 1
time_ms: 860
memory_kb: 3620
final_rank: 4

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;



#define SIZE 4000005

int N,num_data;
int table[SIZE][6],work[6],tri[4][3] = {{0,1,2},{0,3,4},{1,4,5},{2,5,3}};
double A[20];
bool used[20];

void dfs(int index){

	if(index == 6){

		for(int i = 0; i < 6; i++){

			table[num_data][i] = work[i];
		}
		num_data++;

		return;
	}

	for(int i = 0; i < N; i++){
		if(used[i])continue;
		used[i] = true;

		work[index] = i;

		dfs(index+1);
		used[i] = false;
	}
}

//三角形が作れるか
bool check(int table[3]){

	sort(table,table+3);

	return (table[0]+table[1] > table[2]+EPS);
}

double yogen(double a,double b, double c){

	double ret = (b*b+c*c-a*a)/(2*b*c);
	return ret;
}

double calc_V(int index){

	double a = A[table[index][3]];
	double b = A[table[index][4]];
	double c = A[table[index][5]];

	double alpha = yogen(A[table[index][0]],A[table[index][3]],A[table[index][4]]);
	double beta = yogen(A[table[index][1]],A[table[index][4]],A[table[index][5]]);
	double gamma = yogen(A[table[index][2]],A[table[index][5]],A[table[index][3]]);

	double V = (a*b*c)/6.0*sqrt(1+2*alpha*beta*gamma-(alpha*alpha + beta*beta + gamma*gamma));

	return V;
}

void func(){

	for(int i = 0; i < N; i++){

		scanf("%lf",&A[i]);
	}
	num_data = 0;

	for(int i = 0; i < N; i++){

		used[i] = false;
	}

	dfs(0);

	double ans = 0;

	for(int i = 0; i < num_data; i++){

		int TMP[3];

		bool FLG = true;

		for(int k = 0; k < 4; k++){
			for(int p = 0; p < 3; p++){

				TMP[p] = A[table[i][tri[k][p]]];
			}
			if(!check(TMP)){

				FLG = false;
				break;
			}
		}
		if(!FLG)continue;

		double tmp_V = calc_V(i);
		ans = max(ans,tmp_V);
	}

	printf("%.12lf\n",ans);
}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 3580
memory_kb: 87688
final_rank: 20

code_snippet: #include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <algorithm>
#include <cmath>
#include <array>
using namespace std;
const double EPS = 1e-8;
const double INF = 1e12;
#define EQ(n,m) (abs((n)-(m)) < EPS)
#define X real()
#define Y imag()

typedef complex<double> P;
typedef vector<P> VP;
struct L : array<P, 2>{
    L(const P& a, const P& b){ at(0)=a; at(1)=b; }
    L(){}
};
namespace std{
    bool operator < (const P& a, const P& b){
        return (a.X!=b.X) ? a.X<b.X : a.Y<b.Y;
    }
    bool operator == (const P& a, const P& b){
        return abs(a-b) < EPS;
    }
}

double dot(P a, P b){
    return (conj(a)*b).X;
}
double cross(P a, P b){
    return (conj(a)*b).Y;
}
int ccw(P a, P b, P c){
    b -= a;
    c -= a;
    if(cross(b,c) > EPS) return +1; //ccw
    if(cross(b,c) < -EPS) return -1; //cw
    if(dot(b,c) < -EPS) return +2; //c-a-b
    if(abs(c)-abs(b) > EPS) return -2; //a-b-c
    return 0; //a-c-b
}
P unit(const P &p){
    return p/abs(p);
}

P crosspointLL(const L &l, const L &m) {
  double A = cross(l[1]-l[0], m[1]-m[0]);
  double B = cross(l[1]-l[0], l[1]-m[0]);
  return m[0] + B/A *(m[1]-m[0]);
}

int main(){
    while(1){
        int n;
        cin >> n;
        if(n==0) break;

        vector<double> len(n);
        for(int i=0; i<n; i++){
            cin >> len[i];
        }
        vector<bool> choose(n, false);
        for(int i=0; i<3; i++){
            choose[n-i-1] = true;
        }

        double ans = 0;
        do{
            //底面を作る3角形の選び方
            vector<double> base;
            for(int i=0; i<n; i++){
                if(choose[i]) base.push_back(len[i]);
            }
            sort(base.begin(), base.end());
            if(base[0] +base[1] < base[2] +EPS) continue;

            P p[3];
            p[0] = P(0, 0);
            p[1] = P(base[0], 0);
            double c2x = (base[2]*base[2] -base[1]*base[1] +base[0]*base[0]) /(2*base[0]);
            double c2y = sqrt(base[2]*base[2] -c2x*c2x);
            p[2] = P(c2x, c2y);

            //底面から生やす辺の選び方
            for(int i=0; i<n; i++){
                if(choose[i]) continue;
                for(int j=0; j<n; j++){
                    if(choose[j] || j==i) continue;
                    for(int k=0; k<n; k++){
                        if(choose[k] || k==i || k==j) continue;
                        //3角形が作れるか
                        bool ok = true;
                        double hlen[3] = {len[i], len[j], len[k]};
                        L lines[3];
                        for(int d=0; d<3; d++){
                            if(hlen[d] +hlen[(d+1)%3] < base[d] || abs(hlen[d] -hlen[(d+1)%3]) > base[d]){
                                ok = false;
                                break;
                            }
                            double dist = (hlen[d]*hlen[d] -hlen[(d+1)%3]*hlen[(d+1)%3] +base[d]*base[d]) /(2*base[d]);
                            P dir = dist * unit(p[(d+1)%3] -p[d]);
                            lines[d][0] = p[d] +dir;
                            lines[d][1] = lines[d][0] +dir *P(0, 1);
                        }
                        if(ok){
                            P cp1 = crosspointLL(lines[0], lines[1]);
                            double h = sqrt(hlen[0]*hlen[0] -norm(cp1));
                            ans = max(ans, cross(p[1], p[2]) *h /6);
                        }
                    }
                }
            }
        }while(next_permutation(choose.begin(), choose.end()));

        cout << fixed << setprecision(10);
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 3368
final_rank: 2

code_snippet: #include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

bool tri_valid(int a, int b, int c) {
	vector<int>v{ a,b,c };
	sort(v.begin(),v.end());
	return v[2]<v[0]+v[1];
}

ld get_theta(ld a1, ld a2, ld x) {
	return (a1*a1+a2*a2-x*x)/(2*a1*a2);
}

int main() {
	cout<<setprecision(10)<<fixed;
	while (true){
		int N;cin>>N;
		if(!N)break;
		vector<int>sticks(N);
		for(int i=0;i<N;++i)cin>>sticks[i];

		vector<int>av(6);
		ld ans=0;
		for (av[0] = 0; av[0] < N; ++av[0]) {
			for ( av[1] = av[0]+1; av[1] < N; ++av[1]) {
				for ( av[2] = av[1]+1; av[2] < N; ++av[2]) {
					for (av[3] = 0; av[3] < N; ++av[3]) {
						for ( av[4] = 0; av[4] < N; ++av[4]) {
							for ( av[5] = 0; av[5] < N; ++av[5]) {
								bool ok=true;
								for (int i = 0; i < 6; ++i) {
									for (int j = i + 1; j < 6; ++j) {
										if(av[i]==av[j])ok=false;
									}
								}
								if(!ok)continue;
								vector<int>v(6);
								for(int i=0;i<6;++i)v[i]=sticks[av[i]];
								if(!tri_valid(v[0],v[1],v[2]))ok=false;
								for (int i = 0; i < 3; ++i) {
									if(!tri_valid(v[i],v[3+(i+1)%3],v[3+(i+2)%3]))ok=false;
								}
								if(!ok)continue;

								vector<ld>thetas(3);
								for (int i = 0; i < 3; ++i) {
									thetas[i]=get_theta(v[3+(i+1)%3],v[3+(i+2)%3],v[i]);
								}

								ld num=1+2*thetas[0]*thetas[1]*thetas[2]-(pow(thetas[0],2)+pow(thetas[1],2)+pow(thetas[2],2));
								if (num > 0) {
									ans=max(ans,v[3]*v[4]*v[5]*sqrt(num)/6.0);
								}
							}
						}
					}
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}
accuracy: 1
time_ms: 3240
memory_kb: 3112
final_rank: 13

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define EPS (1e-10)
using Int = long long;

//BEGIN CUT HERE
typedef vector<double> arr;
typedef vector<arr> mat;

double det(mat A){
  int n=A.size();
  double res=1;
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i+1;j<n;j++)
      if(abs(A[j][i])>abs(A[pivot][i])) pivot=j;
    swap(A[pivot],A[i]);
    res*=A[i][i]*(i!=pivot?-1:1);
    if(abs(A[i][i])<EPS) break;
    for(int j=i+1;j<n;j++)
      for(int k=n-1;k>=i;k--)
	A[j][k]-=A[i][k]*A[j][i]/A[i][i];
  }
  return res;
}

bool isTriangle(double a1,double a2,double a3){
  if(a1+a2<=a3||a2+a3<=a1||a3+a1<=a2) return 0;
  return 1;
}
double tetrahedra(double OA,double OB,double OC,double AB,double AC,double BC){
  if(!isTriangle(OA,OB,AB)) return 0;
  if(!isTriangle(OB,OC,BC)) return 0;
  if(!isTriangle(OC,OA,AC)) return 0;
  if(!isTriangle(AB,AC,BC)) return 0;
  mat A(5,arr(5,0));
  A[0][0]=    0;A[0][1]=AB*AB;A[0][2]=AC*AC;A[0][3]=OA*OA;A[0][4]=1;
  A[1][0]=AB*AB;A[1][1]=    0;A[1][2]=BC*BC;A[1][3]=OB*OB;A[1][4]=1;
  A[2][0]=AC*AC;A[2][1]=BC*BC;A[2][2]=    0;A[2][3]=OC*OC;A[2][4]=1;
  A[3][0]=OA*OA;A[3][1]=OB*OB;A[3][2]=OC*OC;A[3][3]=    0;A[3][4]=1;
  A[4][0]=    1;A[4][1]=    1;A[4][2]=    1;A[4][3]=    1;A[4][4]=0;
  //cout<<"det(A):"<<det(A)<<endl;
  if(det(A)<=0) return 0; 
  return sqrt(det(A)/288.0);
}
//END CUT HERE

signed main(){
  int n;
  while(cin>>n,n){
    double a[n];
    double ans=0;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++){
      for(int j=i+1;j<n;j++){
	for(int k=j+1;k<n;k++){
	  for(int x=0;x<n;x++){
	    if(i==x||j==x||k==x) continue;
	    for(int y=0;y<n;y++){
	      if(i==y||j==y||k==y||x==y) continue;
	      for(int z=0;z<n;z++){
		if(i==z||j==z||k==z||x==z||y==z) continue;
		ans=max(ans,tetrahedra(a[i],a[j],a[k],a[x],a[y],a[z]));
	      }
	    }
	  }
	}
      }
    }
    printf("%.10f\n",ans);
  }
  return 0;
}


/*
verified on 2017/04/26
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2060
*/
accuracy: 1
time_ms: 1820
memory_kb: 3196
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define EPS (1e-10)
#define int long long

typedef vector<double> arr;
typedef vector<arr> mat;

double det(mat A){
  int n=A.size();
  double res=1;
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i+1;j<n;j++)
      if(abs(A[j][i])>abs(A[pivot][i])) pivot=j;
    swap(A[pivot],A[i]);
    res*=A[i][i]*(i!=pivot?-1:1);
    if(abs(A[i][i])<EPS) break;
    for(int j=i+1;j<n;j++)
      for(int k=n-1;k>=i;k--)
	A[j][k]-=A[i][k]*A[j][i]/A[i][i];
  }
  return res;
}

bool isTriangle(double a1,double a2,double a3){
  if(a1+a2<=a3||a2+a3<=a1||a3+a1<=a2) return 0;
  return 1;
}
double tetrahedra(double OA,double OB,double OC,double AB,double AC,double BC){
  if(!isTriangle(OA,OB,AB)) return 0;
  if(!isTriangle(OB,OC,BC)) return 0;
  if(!isTriangle(OC,OA,AC)) return 0;
  if(!isTriangle(AB,AC,BC)) return 0;
  mat A(5,arr(5,0));
  A[0][0]=    0;A[0][1]=AB*AB;A[0][2]=AC*AC;A[0][3]=OA*OA;A[0][4]=1;
  A[1][0]=AB*AB;A[1][1]=    0;A[1][2]=BC*BC;A[1][3]=OB*OB;A[1][4]=1;
  A[2][0]=AC*AC;A[2][1]=BC*BC;A[2][2]=    0;A[2][3]=OC*OC;A[2][4]=1;
  A[3][0]=OA*OA;A[3][1]=OB*OB;A[3][2]=OC*OC;A[3][3]=    0;A[3][4]=1;
  A[4][0]=    1;A[4][1]=    1;A[4][2]=    1;A[4][3]=    1;A[4][4]=0;
  //cout<<"det(A):"<<det(A)<<endl;
  if(det(A)<=0) return 0; 
  return sqrt(det(A)/288.0);
}
signed main(){
  int n;
  while(cin>>n,n){
    double a[n];
    double ans=0;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++){
      for(int j=i+1;j<n;j++){
	for(int k=j+1;k<n;k++){
	  for(int x=0;x<n;x++){
	    if(i==x||j==x||k==x) continue;
	    for(int y=0;y<n;y++){
	      if(i==y||j==y||k==y||x==y) continue;
	      for(int z=0;z<n;z++){
		if(i==z||j==z||k==z||x==z||y==z) continue;
		ans=max(ans,tetrahedra(a[i],a[j],a[k],a[x],a[y],a[z]));
	      }
	    }
	  }
	}
      }
    }
    printf("%.10f\n",ans);
  }
  return 0;
}


/*
verified on 2017/04/26
http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2060
*/
accuracy: 1
time_ms: 1780
memory_kb: 3080
final_rank: 7

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define EPS (1e-10)
#define int long long

typedef vector<double> arr;
typedef vector<arr> mat;

double det(mat A){
  int n=A.size();
  double res=1;
  for(int i=0;i<n;i++){
    int pivot=i;
    for(int j=i+1;j<n;j++)
      if(abs(A[j][i])>abs(A[pivot][i])) pivot=j;
    swap(A[pivot],A[i]);
    res*=A[i][i]*(i!=pivot?-1:1);
    if(abs(A[i][i])<EPS) break;
    for(int j=i+1;j<n;j++)
      for(int k=n-1;k>=i;k--)
	A[j][k]-=A[i][k]*A[j][i]/A[i][i];
  }
  return res;
}

bool tri(double a1,double a2,double a3){
  if(a1+a2<=a3||a2+a3<=a1||a3+a1<=a2) return 1;
  return 0;
}
double tetrahedra(double OA,double OB,double OC,double AB,double AC,double BC){
  if(tri(OA,OB,AB)) return 0;
  if(tri(OB,OC,BC)) return 0;
  if(tri(OC,OA,AC)) return 0;
  if(tri(AB,AC,BC)) return 0;
  mat A(5,arr(5,0));
  A[0][0]=    0;A[0][1]=AB*AB;A[0][2]=AC*AC;A[0][3]=OA*OA;A[0][4]=1;
  A[1][0]=AB*AB;A[1][1]=    0;A[1][2]=BC*BC;A[1][3]=OB*OB;A[1][4]=1;
  A[2][0]=AC*AC;A[2][1]=BC*BC;A[2][2]=    0;A[2][3]=OC*OC;A[2][4]=1;
  A[3][0]=OA*OA;A[3][1]=OB*OB;A[3][2]=OC*OC;A[3][3]=    0;A[3][4]=1;
  A[4][0]=    1;A[4][1]=    1;A[4][2]=    1;A[4][3]=    1;A[4][4]=0;
  //cout<<"det(A):"<<det(A)<<endl;
  if(det(A)<=0) return 0; 
  return sqrt(det(A)/288.0);
}
signed main(){
  int n;
  while(cin>>n,n){
    double a[n];
    double ans=0;
    for(int i=0;i<n;i++) cin>>a[i];
    for(int i=0;i<n;i++){
      for(int j=i+1;j<n;j++){
	for(int k=j+1;k<n;k++){
	  for(int x=0;x<n;x++){
	    if(i==x||j==x||k==x) continue;
	    for(int y=0;y<n;y++){
	      if(i==y||j==y||k==y||x==y) continue;
	      for(int z=0;z<n;z++){
		if(i==z||j==z||k==z||x==z||y==z) continue;
		ans=max(ans,tetrahedra(a[i],a[j],a[k],a[x],a[y],a[z]));
	      }
	    }
	  }
	}
      }
    }
    printf("%.10f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 1790
memory_kb: 3256
final_rank: 8

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef complex<double> P;
typedef pair<P,double> C;
typedef pair<P,P> L;
 
const double eps=1e-8;
 
bool eq(double a,double b){
  return -eps<a-b&&a-b<eps;
}
 
double cross(P a,P b){
  return imag(b*conj(a));
}
 
bool isCrossCC(C a,C b){
  double ar=a.second, br=b.second;
  double dist=abs(a.first-b.first);
  if( dist > ar+br+eps)return false;
  if( dist > ar+br-eps )return true;
  if( dist > abs(ar-br)+eps)return true;
  if( dist > abs(ar-br)-eps)return true;
  return false;
}
 
double Sqrt(double x){
  if(x<0)return 0;
  return sqrt(x);
}
 
P reflect(P a,P b,P c){
  b-=a;
  c-=a;
  return a+ conj(c/b)*b;
}
 
P getCrossCC(C a,C b){
  P p1=a.first,p2=b.first;
  double r1=a.second, r2=b.second;
  double cA = (r1*r1+norm(p1-p2)-r2*r2) / (2.0*r1*abs(p1-p2));
  return p1+(p2-p1)/abs(p1-p2)*r1*P(cA, Sqrt(1.0-cA*cA) );
}
 
int n;
int t[15];
int u[6];
bool used[15];
double ans=-1;
 
double calcArea(double a,double b,double c){
  P p1=P(0,0);
  P p2=P(b,0);
  P p3=getCrossCC( C(p1,a) , C(p2,c) );
  return abs( cross( p1-p3 , p2-p3 )*0.5 );
}
 
P getCrossLL(L line0,L line1){
  P a=line0.first, b=line0.second;
  P c=line1.first, d=line1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}
 
bool check(int a,int b,int c){
  if(a<b)swap(a,b);
  if(b<c)swap(b,c);
  if(a<b)swap(a,b);
  return ( a < b + c );
}
 
 
void check(){
 
   
  double S=calcArea(u[0],u[1],u[2]);
 
  double h=1e9;
   
  C ca = C( P(0,0) , u[4] );
  C cb = C( P(u[1],0) , u[5] );
  C cc = C( getCrossCC( C(ca.first,u[0]) , C(cb.first,u[2]) ) , u[3] );
 
  if( isCrossCC(ca,cb) == false )return;
  if( isCrossCC(cc,cb) == false )return;
  if( isCrossCC(ca,cc) == false )return;
   
  L fi  = L( getCrossCC(ca,cb) , getCrossCC(cb,ca) );
  if( abs(fi.second-fi.first ) < eps )return;
   
  L se  = L( getCrossCC(cc,ca) , getCrossCC(ca,cc) );
  if( abs(se.second-se.first ) < eps )return;
   
 
  L th = L( getCrossCC(cc,cb) , getCrossCC(cb,cc) );
   
  P target=getCrossLL(fi,se);
 
  P target2 = getCrossLL( th,se);
  if( abs(target-target2) > eps )return;
   
  double di;
   
  di=abs(P(0,0)-target);
  double Ah=min(h, Sqrt(u[4]*u[4]-di*di) );
 
  di=abs(P(u[1],0)-target);
  double Bh=min(h, Sqrt(u[5]*u[5]-di*di) );
 
  di=abs(cc.first-target);
  double Ch=min(h, Sqrt(cc.second*cc.second-di*di) );
  if( !eq(Ah,Ch) )return;
  if( !eq(Ah,Bh) )return;
  if( !eq(Bh,Ch) )return;
  h=min( Ah, Bh);
  h=min( h, Ah);
 
  ans=max(ans, h*S/3.0);
}
 
void dfs(int cnt){
  if(cnt>=3 && !check(u[0],u[1],u[2]))return;
  if(cnt>=5 && !check(u[0],u[3],u[4]))return;
  if(cnt>=6 && !check(u[1],u[4],u[5]))return;
  if(cnt>=6 && !check(u[2],u[3],u[5]))return;
   
  if(cnt==6){
    check();
  }else{
    for(int i=0;i<n;i++){
      if(used[i])continue;
      used[i]=true;
      u[cnt]=t[i];
      dfs(cnt+1);
      used[i]=false;
    }
  }
}
 
int main(){
  while(1){
    scanf("%d",&n);
    if(n==0)break;
     
    for(int i=0;i<n;i++){
      scanf("%d",&t[i]);
    }
 
    sort(t,t+n);
     
    memset(used,false,sizeof(used));
    ans=-1;
    dfs(0);
    printf("%.10f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 6070
memory_kb: 3304
final_rank: 18

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef complex<double> P;
typedef pair<P,double> C;
typedef pair<P,P> L;

const double eps=1e-8;

bool eq(double a,double b){
  return -eps<a-b&&a-b<eps;
}

double cross(P a,P b){
  return imag(b*conj(a));
}

bool isCrossCC(C a,C b){
  double ar=a.second, br=b.second;
  double dist=abs(a.first-b.first);
  if( dist > ar+br+eps)return false;
  if( dist > ar+br-eps )return true;
  if( dist > abs(ar-br)+eps)return true;
  if( dist > abs(ar-br)-eps)return true;
  return false;
}

double Sqrt(double x){
  if(x<0)return 0;
  return sqrt(x);
}

P reflect(P a,P b,P c){
  b-=a;
  c-=a;
  return a+ conj(c/b)*b;
}

P getCrossCC(C a,C b){
  P p1=a.first,p2=b.first;
  double r1=a.second, r2=b.second;
  double cA = (r1*r1+norm(p1-p2)-r2*r2) / (2.0*r1*abs(p1-p2));
  return p1+(p2-p1)/abs(p1-p2)*r1*P(cA, Sqrt(1.0-cA*cA) );
}

int n;
int t[15];
int u[6];
bool used[15];
double ans=-1;

double calcArea(double a,double b,double c){
  P p1=P(0,0);
  P p2=P(b,0);
  P p3=getCrossCC( C(p1,a) , C(p2,c) );
  return abs( cross( p1-p3 , p2-p3 )*0.5 );
}

P getCrossLL(L line0,L line1){
  P a=line0.first, b=line0.second;
  P c=line1.first, d=line1.second;
  a-=d;b-=d;c-=d;
  return d+a+(b-a)*imag(a/c)/imag(a/c-b/c);
}

bool check(int a,int b,int c){
  if(a<b)swap(a,b);
  if(b<c)swap(b,c);
  if(a<b)swap(a,b);
  return ( a < b + c );
}


void check(){

  
  double S=calcArea(u[0],u[1],u[2]);

  double h=1e9;
  
  C ca = C( P(0,0) , u[4] );
  C cb = C( P(u[1],0) , u[5] );
  C cc = C( getCrossCC( C(ca.first,u[0]) , C(cb.first,u[2]) ) , u[3] );

  if( isCrossCC(ca,cb) == false )return;
  if( isCrossCC(cc,cb) == false )return;
  if( isCrossCC(ca,cc) == false )return;
  
  L fi  = L( getCrossCC(ca,cb) , getCrossCC(cb,ca) );
  if( abs(fi.second-fi.first ) < eps )return;
  
  L se  = L( getCrossCC(cc,ca) , getCrossCC(ca,cc) );
  if( abs(se.second-se.first ) < eps )return;
  

  L th = L( getCrossCC(cc,cb) , getCrossCC(cb,cc) );
  
  P target=getCrossLL(fi,se);

  P target2 = getCrossLL( th,se);
  if( abs(target-target2) > eps )return;
  
  double di;
  
  di=abs(P(0,0)-target);
  double Ah=min(h, Sqrt(u[4]*u[4]-di*di) );

  di=abs(P(u[1],0)-target);
  double Bh=min(h, Sqrt(u[5]*u[5]-di*di) );

  di=abs(cc.first-target);
  double Ch=min(h, Sqrt(cc.second*cc.second-di*di) );
  if( !eq(Ah,Ch) )return;
  if( !eq(Ah,Bh) )return;
  if( !eq(Bh,Ch) )return;
  h=min( Ah, Bh);
  h=min( h, Ah);

  ans=max(ans, h*S/3.0);
}

void dfs(int cnt){
  if(cnt>=3 && !check(u[0],u[1],u[2]))return;
  if(cnt>=5 && !check(u[0],u[3],u[4]))return;
  if(cnt>=6 && !check(u[1],u[4],u[5]))return;
  if(cnt>=6 && !check(u[2],u[3],u[5]))return;
  
  if(cnt==6){
    check();
  }else{
    for(int i=0;i<n;i++){
      if(used[i])continue;
      used[i]=true;
      u[cnt]=t[i];
      dfs(cnt+1);
      used[i]=false;
    }
  }
}

int main(){
  while(1){
    scanf("%d",&n);
    if(n==0)break;
    
    for(int i=0;i<n;i++){
      scanf("%d",&t[i]);
    }

    sort(t,t+n);
    
    memset(used,false,sizeof(used));
    ans=-1;
    dfs(0);
    printf("%.10f\n",ans);
  }
  return 0;
}
accuracy: 1
time_ms: 6070
memory_kb: 3324
final_rank: 19

code_snippet: #include <bits/stdc++.h>
  
using namespace std;
  
#define MAX_N 15
  
bool isTri(double a,double b,double c){
    if(c < a+b && a < b+c && b < c+a){
	return true;
    }
    return false;
}
  
double getArea(double a,double b,double c){
    double s = (a+b+c)/2.0;
    return sqrt(s*(s-a)*(s-b)*(s-c));  
}
  
double S(double x){
    return x*x;
}
  
double calc(vector<double> &v){
    double a = S(v[0])*S(v[4])*(S(v[1])+S(v[2])+S(v[3])+S(v[5])-S(v[0])-S(v[4]));
    double b = S(v[1])*S(v[5])*(S(v[0])+S(v[2])+S(v[3])+S(v[4])-S(v[1])-S(v[5]));
    double c = S(v[2])*S(v[3])*(S(v[0])+S(v[1])+S(v[4])+S(v[5])-S(v[2])-S(v[3]));
    double d = -S(v[0])*S(v[1])*S(v[3])-(S(v[1])*S(v[2]))*S(v[4])-
	S(v[0])*S(v[2])*S(v[5])-S(v[3])*S(v[4])*S(v[5]);
    return sqrt((a+b+c+d)/144.0);
}
  
double getVolume(vector<double> &v){
    if(!isTri(v[0],v[1],v[3])) return 0.0; 
    if(!isTri(v[0],v[2],v[5])) return 0.0; 
    if(!isTri(v[1],v[2],v[4])) return 0.0; 
    if(!isTri(v[3],v[4],v[5])) return 0.0; 
    return calc(v);
}
  
double solve(int S,vector<double> &v,vector<double> &a){
    if(__builtin_popcount(S) == 6){
	return getVolume(v);
    }
    double res = 0;
    for(int i = 0 ; i < (int)a.size() ; i++){
	if((S >> i) & 1) continue;
	v.push_back(a[i]);
	res = max(res,solve(S|(1<<i),v,a));
	v.pop_back();
    }
    return res;
}
  
int main(){
    int N;
    while(cin >> N,N){
	vector<double> a(N),v;
	for(int i = 0 ; i < N ; i++){
	    cin >> a[i];
	}
	printf("%.10f\n",solve(0,v,a));
    }
    return 0;
}
accuracy: 1
time_ms: 1550
memory_kb: 3200
final_rank: 6

code_snippet: #include <bits/stdc++.h>
 
using namespace std;
 
#define MAX_N 15
 
bool isTri(double a,double b,double c){
  if(c < a+b && a < b+c && b < c+a){
    return true;
  }
  return false;
}
 
double getArea(double a,double b,double c){
  double s = (a+b+c)/2.0;
  return sqrt(s*(s-a)*(s-b)*(s-c));  
}
 
double S(double x){
  return x*x;
}
 
double calc(vector<double> &v){
  double a = S(v[0])*S(v[4])*(S(v[1])+S(v[2])+S(v[3])+S(v[5])-S(v[0])-S(v[4]));
  double b = S(v[1])*S(v[5])*(S(v[0])+S(v[2])+S(v[3])+S(v[4])-S(v[1])-S(v[5]));
  double c = S(v[2])*S(v[3])*(S(v[0])+S(v[1])+S(v[4])+S(v[5])-S(v[2])-S(v[3]));
  double d = -S(v[0])*S(v[1])*S(v[3])-(S(v[1])*S(v[2]))*S(v[4])-
    S(v[0])*S(v[2])*S(v[5])-S(v[3])*S(v[4])*S(v[5]);
  return sqrt((a+b+c+d)/144.0);
}
 
double getVolume(vector<double> &v){
  if(!isTri(v[0],v[1],v[3])){ return 0.0; }
  if(!isTri(v[0],v[2],v[5])){ return 0.0; }
  if(!isTri(v[1],v[2],v[4])){ return 0.0; }
  if(!isTri(v[3],v[4],v[5])){ return 0.0; }
  return calc(v);
}
 
double solve(int S,vector<double> &v,vector<double> &a){
  if(__builtin_popcount(S) == 6){
    return getVolume(v);
  }
  double res = 0;
  for(int i = 0 ; i < (int)a.size() ; i++){
    if((S >> i) & 1){ continue; }
    v.push_back(a[i]);
    res = max(res,solve(S|(1<<i),v,a));
    v.pop_back();
  }
  return res;
}
 
int main(){
  int N;
  while(cin >> N,N){
    vector<double> a(N),v;
    for(int i = 0 ; i < N ; i++){
      cin >> a[i];
    }
    printf("%.10f\n",solve(0,v,a));
  }
  return 0;
}
accuracy: 1
time_ms: 2440
memory_kb: 1280
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define REP(i,n) for(int i=0; i<(int)(n); ++i)
using namespace std;
typedef long long LL;
bool tri(int a, int b, int c) {
    return a <= b + c && b <= c + a && c <= a + b;
}

double calc(double a, double b, double c, double l, double m, double n) {
    a *= a;
    b *= b;
    c *= c;
    l *= l;
    m *= m;
    n *= n;
    double tmp =
        +a*l*(-a+b+c-l+m+n)
        +b*m*(a-b+c+l-m+n)
        +c*n*(a+b-c+l+m-n)
        -l*b*c-a*m*c-a*b*n-l*m*n;
    if(tmp < 0) return 0;
    return sqrt(tmp) / 12;
}

int main(){
    int num;
    while(cin >> num && num > 0) {
        vector<int> v(num);
        REP(i, num) cin >> v[i];
        double ans = 0.0;
        REP(i, num) REP(j, i) REP(k, j) {
            int l = v[i], m = v[j], n = v[k];
            if(!tri(l, m, n)) continue;
            REP(p, num) if(p != i && p != j && p != k) 
            REP(q, num) if(q != p && q != i && q != j && q != k)
            REP(r, num) if(r != q && r != p && r != i && r != j && r != k) {
                int a = v[p], b = v[q], c = v[r];
                if(!tri(a, b, n)) continue;
                if(!tri(b, c, l)) continue;
                if(!tri(c, a, m)) continue;
                ans = max(ans, calc(a, b, c, l, m, n));
            }
        }
        printf("%.12f\n", ans);
    }
    return 0;
}
accuracy: 1
time_ms: 120
memory_kb: 1220
final_rank: 1

code_snippet: #include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <complex>
#include <cstdio>
using namespace std;

double EPS = 1e-8;
typedef complex<double> P,point;

struct C {P p; double r; C(const P &p,double r) : p(p), r(r){} C(){} };


typedef double number;
const number eps = 1e-8;
typedef vector<number> Array;
typedef vector<Array> matrix;

// O( n )
matrix identity(int n) {
  matrix A(n, Array(n));
  for (int i = 0; i < n; ++i) A[i][i] = 1;
  return A;
}
// O( n )
number inner_product(const Array &a, const Array &b) {
  number ans = 0;
  for (int i = 0; i < a.size(); ++i)
    ans += a[i] * b[i];
  return ans;
}
// O( n^2 )
Array mul(const matrix &A, const Array &x) {
  Array y(A.size());
  for (int i = 0; i < A.size(); ++i)
    for (int j = 0; j < A[0].size(); ++j)
      y[i] = A[i][j] * x[j];
  return y;
}
// O( n^3 )
matrix mul(const matrix &A, const matrix &B) {
  matrix C(A.size(), Array(B[0].size()));
  for (int i = 0; i < C.size(); ++i)
    for (int j = 0; j < C[i].size(); ++j)
      for (int k = 0; k < A[i].size(); ++k)
        C[i][j] += A[i][k] * B[k][j];
  return C;
}
// O( n^3 log e )
matrix pow(const matrix &A, int e) {
  return e == 0 ? identity(A.size())  :
     e % 2 == 0 ? pow(mul(A, A), e/2) : mul(A, pow(A, e-1));
}
// O( n^3 )
number det(matrix A) {
  const int n = A.size();
  number D = 1;
  for (int i = 0; i < n; ++i) {
    int pivot = i;
    for (int j = i+1; j < n; ++j)
      if (abs(A[j][i]) > abs(A[pivot][i])) pivot = j;
    swap(A[pivot], A[i]);
    D *= A[i][i] * (i != pivot ? -1 : 1);
    if (abs(A[i][i]) < eps) break;
    for(int j = i+1; j < n; ++j)
      for(int k = n-1; k >= i; --k)
        A[j][k] -= A[i][k] * A[j][i] / A[i][i];
  }
  return D;
}
// O(n)
number tr(const matrix &A) {
  number ans = 0;
  for (int i = 0; i < A.size(); ++i)
    ans += A[i][i];
  return ans;
}
// O( n^3 ).
int rank(matrix A) {
  const int n = A.size(), m = A[0].size();
  int r = 0;
  for (int i = 0; r < n && i < m; ++i) {
    int pivot = r;
    for (int j = r+1; j < n; ++j)
      if (abs(A[j][i]) > abs(A[pivot][i])) pivot = j;
    swap(A[pivot], A[r]);
    if (abs(A[r][i]) < eps) continue;
    for (int k = m-1; k >= i; --k)
      A[r][k] /= A[r][i];
    for(int j = r+1; j < n; ++j)
      for(int k = i; k < m; ++k)
        A[j][k] -= A[r][k] * A[j][i];
    ++r;
  }
  return r;
}

double chk(double a,double b,double c){
	if( a > b ) swap(a,b);
	if( b > c ) swap(b,c);
	if( a > b ) swap(a,b);
	return a + b >= c;
}
double calc(double a,double b,double c,double d,double e,double f){
	double x = a*a*d*d*(b*b+c*c+e*e+f*f-a*a-d*d)+b*b*e*e*(c*c+a*a+f*f+d*d-b*b-e*e)+c*c*f*f*(a*a+b*b+d*d+e*e-c*c-f*f)-a*a*b*b*c*c-a*a*e*e*f*f-d*d*b*b*f*f-d*d*e*e*c*c;
	return x>0?sqrt(x / 144):0;
}
int main(){
	int N;
	while(cin >> N && N){
		vector<int> t(N);
		double ans = 0;
		vector<int> reflesh(6,0);
		
		int cnt = 0;
		//cout << calc(P(0,0),P(0,1),P(1,1),1,1,1) << endl;
		for(int i = 0 ; i < N ; i++) cin >> t[i];
		sort(t.begin(),t.end());
		for(int i = 0 ; i < (1<<N) ; i++){
			if( __builtin_popcount(i) == 6 ){
				vector<int> v;
				for(int j = 0 ; j < N ; j++) if(i>>j&1)v.push_back(t[j]);
				do{
					double a,b,c,d,e,f;
					tie(a,b,c,d,e,f) = tuple<double,double,double,double,double,double>{v[0],v[1],v[2],v[3],v[4],v[5]};
					if( chk(a,e,f) && chk(a,b,c) && chk(e,d,c) && chk(d,b,f) ){
						ans = max(ans,calc(v[0],v[1],v[2],v[3],v[4],v[5]));
					}
				}while( next_permutation(v.begin(),v.end()) );
			}
		}
		//cout << cnt << endl;
		if(ans == 0){
			for(int i = 0 ; i < N ; i++) cout << t[i] << " "; cout << endl;
		}
		printf("%.10lf%c",ans,10);
	}
}
accuracy: 1
time_ms: 1550
memory_kb: 1232
final_rank: 5

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-7)
#define equals(a,b) (fabs((a)-(b))<EPS)

using namespace std;

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;
const int IINF = INT_MAX;
const int inf = INT_MAX;
//
class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator == (const Segment& p)const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

// a => prev, b => cur, c=> next
// prev から cur へ行って next へ行く際の角度を求める
double getArg(Point a,Point b,Point c){
  double arg1 = atan2(b.y-a.y,b.x-a.x);
  double arg2 = atan2(c.y-b.y,c.x-b.x);
  double arg = fabs( arg1 - arg2 );
  while( arg > M_PI ) arg -= 2.0 * M_PI;
  return fabs(arg);
}
//

// CCW
int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
// CCW END

// intersect
bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2-l.p1, m.p2-m.p1)) > EPS || // non-parallel
         abs(cross(l.p2-l.p1, m.p1-l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2-l.p1, s.p1-l.p1)*       // s[0] is left of l
         cross(l.p2-l.p1, s.p2-l.p1) < EPS; // s[1] is right of l
}
bool intersectLP(Line l,Point p) {
  return abs(cross(l.p2-p, l.p1-p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}
Point reflection(Line l,Point p) {
  return p + (projection(l, p) - p) * 2;
}
double distanceLP(Line l, Point p) {
  return abs(p - projection(l, p));
}
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s)) return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

/*
same lineの時注意
もしm.p1が中心でなかったときに正しい答えとならない
Point crosspoint(Line l,Line m){
  double A = cross(l.p2-l.p1,m.p2-m.p1);
  double B = cross(l.p2-l.p1,l.p2-m.p1);
  if(abs(A) < EPS && abs(B) < EPS){
    vector<Point> vec;
    vec.push_back(l.p1),vec.push_back(l.p2),vec.push_back(m.p1),vec.push_back(m.p2);
    sort(vec.begin(),vec.end());
    assert(vec[1] == vec[2]);
    return vec[1];
    //return m.p1;
  }
  if(abs(A) < EPS)assert(false);
  return m.p1 + (m.p2-m.p1)*(B/A);
}

*/
Point crosspoint(Line l, Line m) {
  double A = cross(l.p2 - l.p1, m.p2 - m.p1);
  double B = cross(l.p2 - l.p1, l.p2 - m.p1);
  if (abs(A) < EPS && abs(B) < EPS) return m.p1; // same line
  if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.p1 +   (m.p2 - m.p1) * (B / A);
}

// intersect END

int array[6000];

double areaT(double a,double b,double c){
  double s = (a+b+c)/2.0;
  return sqrt(s*(s-a)*(s-b)*(s-c));
}

double areaH(double h,double *a){ return ( areaT(a[0],a[1],a[2]) * h) / 3.0; }

bool LTE(double a,double b){ return equals(a,b) || a < b; }

bool LT(double a,double b){ return !equals(a,b) && a < b; }

bool GTE(double a,double b){ return equals(a,b) || a > b; }

bool check1(double a,double b,double c){ return a + b >= c; }

bool checkT(double a,double b,double c){ return LT(a,b+c) && LT(b,a+c) && LT(c,a+b); }

bool check2(double h,double *a){
  if( LTE(a[3]*a[3]-h*h,0) || LTE(a[4]*a[4]-h*h,0) || LTE(a[5]*a[5]-h*h,0) ) return false;
  double L1 = sqrt(a[3]*a[3]-h*h);
  double L2 = sqrt(a[4]*a[4]-h*h);
  double L3 = sqrt(a[5]*a[5]-h*h);
  if( LTE(L1,0) || LTE(L2,0) || LTE(L3,0) ) return false;
  if( !checkT(L1,L2,a[0]) || !checkT(L2,L3,a[2]) || !checkT(L2,L3,a[2]) ) return false;
  cout << endl;
  cout << L1 << " " << L2 << " " << L3 << endl;
  double tmp_area = areaT(L1,L2,a[0]) + areaT(L2,L3,a[2]) + areaT(L1,L3,a[1]);
  cout << tmp_area << " (" << areaT(L1,L2,a[0]) << "+" << areaT(L2,L3,a[2]) << "+" << areaT(L1,L3,a[1]) << ") "<< " ?= " << areaT(a[0],a[1],a[2]) << endl;
  return equals(tmp_area,areaT(a[0],a[1],a[2]));
}

Segment gen(Point p1,Point p2,double a,double b,double c,bool &error){
  double S = areaT(a,b,c);
  cout << "S = " << S << endl;
  double h = 2 * S / a;
  if( LTE(h,0) ) error = true;
  if( LTE(b*b-h*h,0) ) error = true;
  if( error ) return Segment();
  cout << c * c << " - " << h*h << endl;  
double x = sqrt(c*c-h*h);
    cout << h << "," << x << endl;
  Segment seg;
  seg.p1 = p1;
  Vector v = p2 - p1;
  Vector ve = v / abs(v);
  seg.p2 = p1 + ve * x;
  cout << v << endl;
  v = rotate(v,toRad(90));
  cout << v << endl;
  ve = v / abs(v);
  seg.p2 = seg.p2 + ve * h;
  return seg;
}

//
  typedef vector<int> VI;
  typedef vector<VI> VVI;
  typedef VVI matrix;



matrix identity(int n)
{
  matrix A(n,vector<int>(n));
  for(int i=0;i<n;i++) A[i][i] = 1;
  return A;
}


vector<int> multi(const matrix& A,const vector<int>& B)
{
  vector<int> ret(A.size());
  for(int i=0;i<A.size();++i)
    for(int j=0;j<A[0].size();++j)
      ret[i] += A[i][j]*B[j];
  return ret;
}


matrix multi(const matrix& A,const matrix& B)
{
  matrix C(A.size(),vector<int>(B[0].size()));
  for(int i=0;i<C.size();++i)
    for(int j=0;j<C[i].size();++j)
      for(int k=0;k<A[i].size();++k)
	C[i][j] += A[i][k]*B[k][j];
  return C;
}



matrix pow(const matrix& A,int e)
{
  return !e?identity(A.size()):
    (e%2?multi(A,pow(A,e-1)):pow(multi(A,A),e/2));
}
/*
冪乗に関するちょいと解説
行列をAする
A^2 = A*A, A^4 = (A^2)*(A^2), A^8 = (A^4)*(A^4) ・・・・と計算している
行列に限ったことでなく、普通の値の冪乗でも同じように考えることができる
*/


int extgcd(int a,int b,int& x,int& y)
{
  int d = a;
  if(b != 0){
    d = extgcd(b,a%b,y,x);
    y -= (a/b)*x;
  }
  else
    x = 1,y = 0;
  return d;
}

int mod_inv(int a,int m)
{
  int x,y;
  extgcd(a,m,x,y);
  return (m+x%m)%m;
}


int rank(vector<vector<int> > A,int mod)
{
  int H = A.size(), W = A[0].size();
  int r = 0;
  rep(x,W)
    {  
      int pivot = inf;
      REP(y,r,H)
	if(A[y][x])
	  {
	    pivot = y;
	    break;
	  }
      if(pivot == inf)continue;
      swap(A[r],A[pivot]);

      REP(y,r+1,H)
	{
	  int value = A[y][x] * mod_inv(A[r][x],mod) % mod;
	  if(value)REP(x2,x,W)
		     A[y][x2] = ((A[y][x2] - A[r][x2] * value)%mod + mod ) % mod; 
	}
      r++;
    }
  return r;
}


/*

Ax=bが解を持つ必要十分条件は、
rank(A) = rank(A|b)
であり、
Ax=bが一意の解を持つ必要十分条件は、
rank(A) = rank(A|b) = n
*/

bool modGaussElimination(vector<vector<int> > &A, vector<int> &b, int m, vector<int> &res) {
  int n = A.size();
  vector<vector<int> > B(n, vector<int>(n+1));
  rep(i,n) rep(j,n)
    B[i][j] = A[i][j];
  rep(i, n) B[i][n] = b[i];
  
  int nowy = 0;
  rep(x, n) {
    int pivot = -1;
    for (int j=nowy; j<n; ++j)
      if (B[j][x]) {
        pivot = j;break;
      }
    if (pivot == -1) continue;
    swap(B[nowy], B[pivot]);

    for (int j=nowy+1; j<n; ++j) {
      int t = B[j][x] * mod_inv(B[nowy][x], m) % m;
      if (t)
        for (int k=x; k<=n; ++k)
          B[j][k] = ((B[j][k] - B[nowy][k] * t)%m + m )%m;
    }
    nowy++;
    
  }

  res.clear();
  for (int y=nowy; y<n; ++y)
    if (B[y][n])                // rank(A) != rank(A|b)
      return 0;
  if (nowy != n) {              // rank(A) == rank(A|b) != n
    // 解が一意でない。ひとつ求める
    res = vector<int>(n,inf);           // INFは任意を表す
    for (int y=n-1; y>=0; --y) {
      int x;
      for (x=y; x<n; ++x) {
        if (B[y][x])
          break;
      }
      if (x==n) continue;
      int sum = B[y][n];
      
      for (int i=x+1; i<n; ++i) {
        if (res[i] == inf) res[i] = 0; // この時点でres[i]が決まってなかったら0とする
        sum = ((sum - res[i] * B[y][i])%m + m)%m;
      }
      res[x] = sum * mod_inv(B[y][x], m) % m;
    }
    rep(i, n) if (res[i]==inf) res[i] = 0;
    return 0;
  }
  // 解が一意に決まる。普通に後退代入
  res.resize(n);
  for (int x=n-1; x>=0; --x) {
    int sum = B[x][n];
    for (int i=n-1; i>x; --i) {
      sum = ((sum - res[i] * B[x][i])%m + m)%m; 
    }
    res[x] = sum * mod_inv(B[x][x], m) % m;
  }
  return 1;
}

//double det(vector<vector<double> > &A) {
double det(double A[5][5]){
  const int n = 5;
  double D = 1;
  for (int i = 0; i < n; ++i) {
    int pivot = i;
    for (int j = i+1; j < n; ++j)
      if (abs(A[j][i]) > abs(A[pivot][i])) pivot = j;
    swap(A[pivot], A[i]);
    D *= A[i][i] * (i != pivot ? -1 : 1);
    if (abs(A[i][i]) < EPS) break;
    for(int j = i+1; j < n; ++j)
      for(int k = n-1; k >= i; --k)
        A[j][k] -= A[i][k] * A[j][i] / A[i][i];
  }
  return D;
}


//

double getAreaTetrahedra(double *A){
  double a = A[3], b = A[1], c = A[0], p = A[5], q = A[4], r = A[2];

  /*
  vector<vector<double> > mat(5,vector<double>(5,0));
  mat[0][1] = p*p, mat[0][2] = q*q, mat[0][3] = a*a, mat[0][4] = 1;
  mat[1][0] = p*p, mat[1][2] = r*r, mat[1][3] = b*b, mat[1][4] = 1;
  mat[2][0] = q*q, mat[2][1] = r*r, mat[2][3] = c*c, mat[2][4] = 1;
  mat[3][0] = a*a, mat[3][1] = b*b, mat[3][2] = c*c, mat[3][4] = 1;
  mat[4][0] = 1,   mat[4][1] = 1,   mat[4][2] = 1,   mat[4][3] = 1;
  */
  double mat[5][5] = {{0,p*p,q*q,a*a,1},{p*p,0,r*r,b*b,1},{q*q,r*r,0,c*c,1},{a*a,b*b,c*c,0,1},{1,1,1,1,0}};
  return sqrt(det(mat)/288.0);
}

double calc(double *a){
  double ret = 0;
  do{
  if( !checkT(a[0],a[1],a[2]) || !checkT(a[0],a[3],a[4]) || !checkT(a[1],a[3],a[5]) || !checkT(a[2],a[4],a[5]) ) continue;
  /*
    Point p1(0,0);
    Point p2(a[1],0);
    double theta = acos( ( a[0]*a[0] + a[1]*a[1] - a[2]*a[2] ) / ( 2*a[0]*a[1] ) );
    Point p3(a[0]*cos(theta),a[0]*sin(theta));
    //cout << p1 << " " << p2 << " " << p3 << endl;
    double A = a[1], b =a[0], c = a[2];
    double x0 = (A*A-b*b-c*c)/(2*A);
    //cout << "(" << (A*A-b*b-c*c)/(2*A) << "," << sqrt(b*b-x0*x0)<<")"<<endl;
    */
    //if( error ) continue;
    //if( error ) continue;
    //if( LTE(a[3]*a[3]-x*x,0) ) continue;
    //if( LTE(h,0) ) continue;
    ret = max(ret,getAreaTetrahedra(a));
    }while(next_permutation(a,a+6));
    return ret;
}

int main(){
  /*
  double a[6] = {2,2,2,2,2,2};
  cout << calc(a) << endl;
  return 0;
  */
  int dex = 0;
  rep(i,(1<<15)) if( __builtin_popcount(i) == 6 ) array[dex++] = i;
  int N,input[16];
  while( scanf("%d",&N), N ){
    rep(i,N) scanf("%d",input+i);
    sort(input,input+N);
    double maxi = 0;
    rep(k,dex){
      int bitmask = array[k];
      if( bitmask >= (1<<N) ) break;
      double buf[6];
      int cur = 0;
      rep(j,N) if( (bitmask>>j) & 1 ) buf[cur++] = input[j];
      maxi = max(maxi,calc(buf));
    }
    printf("%.10f\n",maxi);
  }
  return 0;
}
accuracy: 1
time_ms: 5320
memory_kb: 1288
final_rank: 16

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define EPS (1e-7)
#define equals(a,b) (fabs((a)-(b))<EPS)

using namespace std;

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;
const int IINF = INT_MAX;
const int inf = INT_MAX;
//
class Point{
public:
  double x,y;

  Point(double x = -IINF,double y = -IINF): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator == (const Segment& p)const { return p.p1 == p1 && p.p2 == p2; }
};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

// a => prev, b => cur, c=> next
// prev から cur へ行って next へ行く際の角度を求める
double getArg(Point a,Point b,Point c){
  double arg1 = atan2(b.y-a.y,b.x-a.x);
  double arg2 = atan2(c.y-b.y,c.x-b.x);
  double arg = fabs( arg1 - arg2 );
  while( arg > M_PI ) arg -= 2.0 * M_PI;
  return fabs(arg);
}
//

// CCW
int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}
// CCW END

// intersect
bool intersectLL(Line l, Line m) {
  return abs(cross(l.p2-l.p1, m.p2-m.p1)) > EPS || // non-parallel
         abs(cross(l.p2-l.p1, m.p1-l.p1)) < EPS;   // same line
}
bool intersectLS(Line l, Line s) {
  return cross(l.p2-l.p1, s.p1-l.p1)*       // s[0] is left of l
         cross(l.p2-l.p1, s.p2-l.p1) < EPS; // s[1] is right of l
}
bool intersectLP(Line l,Point p) {
  return abs(cross(l.p2-p, l.p1-p)) < EPS;
}
bool intersectSS(Line s, Line t) {
  return ccw(s.p1,s.p2,t.p1)*ccw(s.p1,s.p2,t.p2) <= 0 &&
         ccw(t.p1,t.p2,s.p1)*ccw(t.p1,t.p2,s.p2) <= 0;
}
bool intersectSP(Line s, Point p) {
  return abs(s.p1-p)+abs(s.p2-p)-abs(s.p2-s.p1) < EPS; // triangle inequality
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}
Point reflection(Line l,Point p) {
  return p + (projection(l, p) - p) * 2;
}
double distanceLP(Line l, Point p) {
  return abs(p - projection(l, p));
}
double distanceLL(Line l, Line m) {
  return intersectLL(l, m) ? 0 : distanceLP(l, m.p1);
}

double distanceLS(Line l, Line s) {
  if (intersectLS(l, s)) return 0;
  return min(distanceLP(l, s.p1), distanceLP(l, s.p2));
}
double distanceSP(Line s, Point p) {
  Point r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.p1 - p), abs(s.p2 - p));
}

double distanceSS(Line s, Line t) {
  if (intersectSS(s, t)) return 0;
  return min(min(distanceSP(s, t.p1), distanceSP(s, t.p2)),
             min(distanceSP(t, s.p1), distanceSP(t, s.p2)));
}

/*
same lineの時注意
もしm.p1が中心でなかったときに正しい答えとならない
Point crosspoint(Line l,Line m){
  double A = cross(l.p2-l.p1,m.p2-m.p1);
  double B = cross(l.p2-l.p1,l.p2-m.p1);
  if(abs(A) < EPS && abs(B) < EPS){
    vector<Point> vec;
    vec.push_back(l.p1),vec.push_back(l.p2),vec.push_back(m.p1),vec.push_back(m.p2);
    sort(vec.begin(),vec.end());
    assert(vec[1] == vec[2]);
    return vec[1];
    //return m.p1;
  }
  if(abs(A) < EPS)assert(false);
  return m.p1 + (m.p2-m.p1)*(B/A);
}

*/
Point crosspoint(Line l, Line m) {
  double A = cross(l.p2 - l.p1, m.p2 - m.p1);
  double B = cross(l.p2 - l.p1, l.p2 - m.p1);
  if (abs(A) < EPS && abs(B) < EPS) return m.p1; // same line
  if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m.p1 +   (m.p2 - m.p1) * (B / A);
}

// intersect END

int array[6000];

double areaT(double a,double b,double c){
  double s = (a+b+c)/2.0;
  return sqrt(s*(s-a)*(s-b)*(s-c));
}

double areaH(double h,double *a){ return ( areaT(a[0],a[1],a[2]) * h) / 3.0; }

bool LTE(double a,double b){ return equals(a,b) || a < b; }

bool LT(double a,double b){ return !equals(a,b) && a < b; }

bool GTE(double a,double b){ return equals(a,b) || a > b; }

bool check1(double a,double b,double c){ return a + b >= c; }

bool checkT(double a,double b,double c){ return LT(a,b+c) && LT(b,a+c) && LT(c,a+b); }

bool check2(double h,double *a){
  if( LTE(a[3]*a[3]-h*h,0) || LTE(a[4]*a[4]-h*h,0) || LTE(a[5]*a[5]-h*h,0) ) return false;
  double L1 = sqrt(a[3]*a[3]-h*h);
  double L2 = sqrt(a[4]*a[4]-h*h);
  double L3 = sqrt(a[5]*a[5]-h*h);
  if( LTE(L1,0) || LTE(L2,0) || LTE(L3,0) ) return false;
  if( !checkT(L1,L2,a[0]) || !checkT(L2,L3,a[2]) || !checkT(L2,L3,a[2]) ) return false;
  cout << endl;
  cout << L1 << " " << L2 << " " << L3 << endl;
  double tmp_area = areaT(L1,L2,a[0]) + areaT(L2,L3,a[2]) + areaT(L1,L3,a[1]);
  cout << tmp_area << " (" << areaT(L1,L2,a[0]) << "+" << areaT(L2,L3,a[2]) << "+" << areaT(L1,L3,a[1]) << ") "<< " ?= " << areaT(a[0],a[1],a[2]) << endl;
  return equals(tmp_area,areaT(a[0],a[1],a[2]));
}

Segment gen(Point p1,Point p2,double a,double b,double c,bool &error){
  double S = areaT(a,b,c);
  cout << "S = " << S << endl;
  double h = 2 * S / a;
  if( LTE(h,0) ) error = true;
  if( LTE(b*b-h*h,0) ) error = true;
  if( error ) return Segment();
  cout << c * c << " - " << h*h << endl;  
double x = sqrt(c*c-h*h);
    cout << h << "," << x << endl;
  Segment seg;
  seg.p1 = p1;
  Vector v = p2 - p1;
  Vector ve = v / abs(v);
  seg.p2 = p1 + ve * x;
  cout << v << endl;
  v = rotate(v,toRad(90));
  cout << v << endl;
  ve = v / abs(v);
  seg.p2 = seg.p2 + ve * h;
  return seg;
}

//
  typedef vector<int> VI;
  typedef vector<VI> VVI;
  typedef VVI matrix;



matrix identity(int n)
{
  matrix A(n,vector<int>(n));
  for(int i=0;i<n;i++) A[i][i] = 1;
  return A;
}


vector<int> multi(const matrix& A,const vector<int>& B)
{
  vector<int> ret(A.size());
  for(int i=0;i<A.size();++i)
    for(int j=0;j<A[0].size();++j)
      ret[i] += A[i][j]*B[j];
  return ret;
}


matrix multi(const matrix& A,const matrix& B)
{
  matrix C(A.size(),vector<int>(B[0].size()));
  for(int i=0;i<C.size();++i)
    for(int j=0;j<C[i].size();++j)
      for(int k=0;k<A[i].size();++k)
	C[i][j] += A[i][k]*B[k][j];
  return C;
}



matrix pow(const matrix& A,int e)
{
  return !e?identity(A.size()):
    (e%2?multi(A,pow(A,e-1)):pow(multi(A,A),e/2));
}
/*
冪乗に関するちょいと解説
行列をAする
A^2 = A*A, A^4 = (A^2)*(A^2), A^8 = (A^4)*(A^4) ・・・・と計算している
行列に限ったことでなく、普通の値の冪乗でも同じように考えることができる
*/


int extgcd(int a,int b,int& x,int& y)
{
  int d = a;
  if(b != 0){
    d = extgcd(b,a%b,y,x);
    y -= (a/b)*x;
  }
  else
    x = 1,y = 0;
  return d;
}

int mod_inv(int a,int m)
{
  int x,y;
  extgcd(a,m,x,y);
  return (m+x%m)%m;
}


int rank(vector<vector<int> > A,int mod)
{
  int H = A.size(), W = A[0].size();
  int r = 0;
  rep(x,W)
    {  
      int pivot = inf;
      REP(y,r,H)
	if(A[y][x])
	  {
	    pivot = y;
	    break;
	  }
      if(pivot == inf)continue;
      swap(A[r],A[pivot]);

      REP(y,r+1,H)
	{
	  int value = A[y][x] * mod_inv(A[r][x],mod) % mod;
	  if(value)REP(x2,x,W)
		     A[y][x2] = ((A[y][x2] - A[r][x2] * value)%mod + mod ) % mod; 
	}
      r++;
    }
  return r;
}


/*

Ax=bが解を持つ必要十分条件は、
rank(A) = rank(A|b)
であり、
Ax=bが一意の解を持つ必要十分条件は、
rank(A) = rank(A|b) = n
*/

bool modGaussElimination(vector<vector<int> > &A, vector<int> &b, int m, vector<int> &res) {
  int n = A.size();
  vector<vector<int> > B(n, vector<int>(n+1));
  rep(i,n) rep(j,n)
    B[i][j] = A[i][j];
  rep(i, n) B[i][n] = b[i];
  
  int nowy = 0;
  rep(x, n) {
    int pivot = -1;
    for (int j=nowy; j<n; ++j)
      if (B[j][x]) {
        pivot = j;break;
      }
    if (pivot == -1) continue;
    swap(B[nowy], B[pivot]);

    for (int j=nowy+1; j<n; ++j) {
      int t = B[j][x] * mod_inv(B[nowy][x], m) % m;
      if (t)
        for (int k=x; k<=n; ++k)
          B[j][k] = ((B[j][k] - B[nowy][k] * t)%m + m )%m;
    }
    nowy++;
    
  }

  res.clear();
  for (int y=nowy; y<n; ++y)
    if (B[y][n])                // rank(A) != rank(A|b)
      return 0;
  if (nowy != n) {              // rank(A) == rank(A|b) != n
    // 解が一意でない。ひとつ求める
    res = vector<int>(n,inf);           // INFは任意を表す
    for (int y=n-1; y>=0; --y) {
      int x;
      for (x=y; x<n; ++x) {
        if (B[y][x])
          break;
      }
      if (x==n) continue;
      int sum = B[y][n];
      
      for (int i=x+1; i<n; ++i) {
        if (res[i] == inf) res[i] = 0; // この時点でres[i]が決まってなかったら0とする
        sum = ((sum - res[i] * B[y][i])%m + m)%m;
      }
      res[x] = sum * mod_inv(B[y][x], m) % m;
    }
    rep(i, n) if (res[i]==inf) res[i] = 0;
    return 0;
  }
  // 解が一意に決まる。普通に後退代入
  res.resize(n);
  for (int x=n-1; x>=0; --x) {
    int sum = B[x][n];
    for (int i=n-1; i>x; --i) {
      sum = ((sum - res[i] * B[x][i])%m + m)%m; 
    }
    res[x] = sum * mod_inv(B[x][x], m) % m;
  }
  return 1;
}

//double det(vector<vector<double> > &A) {
double det(double A[5][5]) {
  const int n = 5;
  double D = 1;
  for (int i = 0; i < n; ++i) {
    int pivot = i;
    for (int j = i+1; j < n; ++j)
      if (abs(A[j][i]) > abs(A[pivot][i])) pivot = j;
    swap(A[pivot], A[i]);
    D *= A[i][i] * (i != pivot ? -1 : 1);
    if (abs(A[i][i]) < EPS) break;
    for(int j = i+1; j < n; ++j)
      for(int k = n-1; k >= i; --k)
        A[j][k] -= A[i][k] * A[j][i] / A[i][i];
  }
  return D;
}


//

double getAreaTetrahedra(double *A){
  double a = A[3], b = A[1], c = A[0], p = A[5], q = A[4], r = A[2];

  /*
  vector<vector<double> > mat(5,vector<double>(5,0));
  mat[0][1] = p*p, mat[0][2] = q*q, mat[0][3] = a*a, mat[0][4] = 1;
  mat[1][0] = p*p, mat[1][2] = r*r, mat[1][3] = b*b, mat[1][4] = 1;
  mat[2][0] = q*q, mat[2][1] = r*r, mat[2][3] = c*c, mat[2][4] = 1;
  mat[3][0] = a*a, mat[3][1] = b*b, mat[3][2] = c*c, mat[3][4] = 1;
  mat[4][0] = 1,   mat[4][1] = 1,   mat[4][2] = 1,   mat[4][3] = 1;
  */
  double mat[5][5] = {{0,p*p,q*q,a*a,1},{p*p,0,r*r,b*b,1},{q*q,r*r,0,c*c,1},{a*a,b*b,c*c,0,1},{1,1,1,1,0}};
  return det(mat)/288.0;
}

double calc(double *a){
  double ret = 0;
  do{
  if( !checkT(a[0],a[1],a[2]) || !checkT(a[0],a[3],a[4]) || !checkT(a[1],a[3],a[5]) || !checkT(a[2],a[4],a[5]) ) continue;
  /*
    Point p1(0,0);
    Point p2(a[1],0);
    double theta = acos( ( a[0]*a[0] + a[1]*a[1] - a[2]*a[2] ) / ( 2*a[0]*a[1] ) );
    Point p3(a[0]*cos(theta),a[0]*sin(theta));
    //cout << p1 << " " << p2 << " " << p3 << endl;
    double A = a[1], b =a[0], c = a[2];
    double x0 = (A*A-b*b-c*c)/(2*A);
    //cout << "(" << (A*A-b*b-c*c)/(2*A) << "," << sqrt(b*b-x0*x0)<<")"<<endl;
    */
    //if( error ) continue;
    //if( error ) continue;
    //if( LTE(a[3]*a[3]-x*x,0) ) continue;
    //if( LTE(h,0) ) continue;
    ret = max(ret,sqrt(getAreaTetrahedra(a)));
    }while(next_permutation(a,a+6));
    return ret;
}

int main(){
  /*
  double a[6] = {2,2,2,2,2,2};
  cout << calc(a) << endl;
  return 0;
  */
  int dex = 0;
  rep(i,(1<<15)) if( __builtin_popcount(i) == 6 ) array[dex++] = i;
  int N,input[16];
  while( scanf("%d",&N), N ){
    rep(i,N) scanf("%d",input+i);
    sort(input,input+N);
    double maxi = 0;
    rep(k,dex){
      int bitmask = array[k];
      if( bitmask >= (1<<N) ) break;
      double buf[6];
      int cur = 0;
      rep(j,N) if( (bitmask>>j) & 1 ) buf[cur++] = input[j];
      maxi = max(maxi,calc(buf));
    }
    printf("%.10f\n",maxi);
  }
  return 0;
}
accuracy: 1
time_ms: 5250
memory_kb: 1288
final_rank: 15

code_snippet: #include<iostream>
#include<cmath>
#include<cstdio>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)

double a[20];
int index[6], n;

bool ng(double a, double b, double c) {
  if (a + b <= c) return true;
  if (b + c <= a) return true;
  if (c + a <= b) return true;
  return false;
}
				       

double solve(int m) {
  if (m == 6) {
    if (ng(a[index[0]], a[index[1]], a[index[2]])) return 0;
    if (ng(a[index[0]], a[index[3]], a[index[4]])) return 0;
    if (ng(a[index[1]], a[index[4]], a[index[5]])) return 0;
    if (ng(a[index[2]], a[index[5]], a[index[3]])) return 0;
    double aa[3], bb[3], t, pi[4];
    aa[0] = a[index[0]];
    aa[1] = a[index[1]];
    aa[2] = a[index[2]];
    bb[0] = a[index[5]];
    bb[1] = a[index[3]];
    bb[2] = a[index[4]];
    t = 0;
    rep (i, 3) t += aa[i] * aa[i];
    rep (i, 3) t += bb[i] * bb[i];
    t = sqrt(max(t, 0.));
    pi[0] = aa[0] * aa[1] * aa[2];
    pi[1] = aa[0] * bb[1] * bb[2];
    pi[2] = aa[1] * bb[2] * bb[0];
    pi[3] = aa[2] * bb[0] * bb[1];
    double v = 0;
    rep (i, 3) v += aa[i] * aa[i] * bb[i] * bb[i] * (t * t- 2 * aa[i] * aa[i] - 2 * bb[i] * bb[i]);
    rep (i, 4) v -= pi[i] * pi[i];
    return sqrt(max(v, 0.)) / 12;
  }
  double res = 0;
  rep (i, n) {
    bool ok = true;
    rep (j, m) if (index[j] == i) ok = false;
    if (ok) {
      index[m] = i;
      res = max(solve(m + 1), res);
    }
  }
  return res;
}

int main() {
  while (true) {
    cin >> n;
    if (n == 0) break;
    rep (i, n) cin >> a[i];
    printf("%.12f\n", solve(0));
  }
  return 0;
}
accuracy: 1
time_ms: 2390
memory_kb: 1244
final_rank: 10

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const double EPS = 1.0e-10;

double determinant(vector<vector<double> > mat)
{   
    const int n = mat.size();
    double ret = 1.0;
    for(int i=0; i<n; ++i){
        int tmp = i;
        for(int j=i+1; j<n; ++j){
            if(abs(mat[j][i]) > abs(mat[tmp][i]))
                tmp = j;
        }
        if(abs(mat[tmp][i]) < EPS)
            return 0.0;
        if(tmp != i){
            mat[i].swap(mat[tmp]);
            ret *= -1.0;
        }

        for(int j=i+1; j<n; ++j){
            for(int k=n-1; k>=i; --k){
                mat[j][k] -= mat[i][k] * (mat[j][i] / mat[i][i]);
            }
        }
        ret *= mat[i][i];
    }
    return ret;
}

double tetrahedronVolume(const vector<double>& len)
{
    const int a[][3] = {{0,1,3}, {1,2,4}, {0,2,5}, {3,4,5}};
    for(int i=0; i<4; ++i){
        vector<double> b(3);
        for(int j=0; j<3; ++j)
            b[j] = len[a[i][j]];
        sort(b.begin(), b.end());
        if(b[2] > b[0] + b[1] - EPS)
            return 0.0;
    }

    const int y[] = {0, 3, 1, 3, 2, 3, 0, 1, 1, 2, 0, 2};
    const int x[] = {3, 0, 3, 1, 3, 2, 1, 0, 2, 1, 2, 0};

    vector<vector<double> > mat(5, vector<double>(5, 1.0));
    for(int i=0; i<12; ++i)
        mat[y[i]][x[i]] = pow(len[i/2], 2.0);
    for(int i=0; i<5; ++i)
        mat[i][i] = 0.0;

    return sqrt(determinant(mat) / 288.0);
}

template <size_t T>
bool nextBitset(bitset<T> &bs, int digit)
{
    if(bs.none())
        return false;
    bitset<T> x, y, z;
    x = bs.to_ulong() & (~(bs.to_ulong()) + 1ULL);
    y = bs.to_ulong() + x.to_ulong() + 0ULL;
    z = bs & ~y;
    if(bs[digit-1] && bs == z)
        return false;
    bs = ((z.to_ulong() / x.to_ulong()) >> 1) + 0ULL;
    bs |= y;
    return true;
}

int main()
{
    for(;;){
        int n;
        cin >> n;
        if(n == 0)
            return 0;

        vector<double> len(n);
        for(int i=0; i<n; ++i)
            cin >> len[i];

        double ret = 0.0;
        bitset<15> used;
        for(int i=0; i<n; ++i){
            for(int j=0; j<i; ++j){
                for(int k=0; k<j; ++k){
                    used[i] = used[j] = used[k] = true;

                    for(int a=0; a<n; ++a){
                        for(int b=0; b<n; ++b){
                            for(int c=0; c<n; ++c){
                                if(a == b || b == c || c == a)
                                    continue;
                                if(used[a] || used[b] || used[c])
                                    continue;

                                vector<double> len2(6);
                                len2[0] = len[a];
                                len2[1] = len[b];
                                len2[2] = len[c];
                                len2[3] = len[i];
                                len2[4] = len[j];
                                len2[5] = len[k];
                                ret = max(ret, tetrahedronVolume(len2));
                                ;
                            }
                        }
                    }

                    used[i] = used[j] = used[k] = false;
                }
            }
        }

        printf("%.10f\n", ret);
    }
}
accuracy: 1
time_ms: 3930
memory_kb: 1272
final_rank: 14

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

typedef long long ll;

int n;
int t[20];
vector<int> v[20];

void makePattern(int idx, int cnt, int bit){
  if(cnt > 6) return;
  if(idx == n){
    if(cnt == 6){
      v[n].push_back(bit);
    }
    return;
  }

  makePattern(idx + 1, cnt, bit);
  makePattern(idx + 1, cnt + 1, bit | (1 << idx));
}

bool check(ll x, ll y, ll z){
  return x + y > z && x + z > y && y + z > x;
}

void solve(){
  double ans = 0;

  for(int i = 0; i < v[n].size(); i++){
    vector<int> a;

    for(int j = 0; j < n; j++){
      if(v[n][i] & (1 << j)){
        a.push_back(t[j]);
      }
    }

    sort(a.begin(), a.end());

    do{
      ll A = a[0];
      ll B = a[1];
      ll C = a[2];
      ll X = a[3];
      ll Y = a[4];
      ll Z = a[5];

      if(!check(A, B, C) || !check(A, Y, Z) ||
         !check(B, X, Z) || !check(C, Y, Z)){
        continue;
      }

      A *= A;
      B *= B;
      C *= C;
      X *= X;
      Y *= Y;
      Z *= Z;

      ll V =
        A * X * (B + C - A + Y + Z - X) +
        B * Y * (C + A - B + Z + X - Y) +
        C * Z * (A + B - C + X + Y - Z) -
        A * Y * Z -
        B * Z * X -
        C * X * Y -
        A * B * C;

      ans = max(ans, sqrt((double)V / 144));
    }while(next_permutation(a.begin(), a.end()));
  }

  printf("%.6f\n", ans);
}

int main(){
  for(n = 6; n <= 15; n++){
    makePattern(0, 0, 0);
  }

  while(cin >> n, n){
    for(int i = 0; i < n; i++){
      cin >> t[i];
    }
    solve();
  }
}
accuracy: 1
time_ms: 5420
memory_kb: 1052
final_rank: 17