Problem p01183 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

int N;
int a[20];
double opt;
int getNum[20];
int sel[20];

const double EPS = (1e-10);
bool EQ(double a, double b) { return abs(a - b) < EPS; }

bool check(int *tmparry) {
  sort(tmparry, tmparry + 3);
  return (tmparry[2] < tmparry[0] + tmparry[1]);
}
void dfs(int pos, int cur) {
  if (pos == 6) {
    for (int i = 0; i < 6; i++)
      sel[i] = getNum[i];
    sort(sel, sel + 6);
    // 6!通りの組み合わせをすべて試す
    do {
      int tmparry[3];
      for (int i = 0; i < 3; i++)
        tmparry[i] = a[sel[i]];
      if (!check(tmparry))
        continue;
      tmparry[0] = a[sel[0]];
      tmparry[1] = a[sel[4]];
      tmparry[2] = a[sel[3]];
      if (!check(tmparry))
        continue;
      tmparry[0] = a[sel[2]];
      tmparry[1] = a[sel[5]];
      tmparry[2] = a[sel[3]];
      if (!check(tmparry))
        continue;
      tmparry[0] = a[sel[1]];
      tmparry[1] = a[sel[5]];
      tmparry[2] = a[sel[4]];
      if (!check(tmparry))
        continue;
      double theta =
          a[sel[1]] * a[sel[1]] + a[sel[4]] * a[sel[4]] - a[sel[5]] * a[sel[5]];
      theta /= (2.0 * a[sel[1]] * a[sel[4]]);
      theta = acos(theta);
      double x0 = a[sel[4]] * cos(theta);
      double y0 = a[sel[4]] * sin(theta);
      double a0 = a[sel[1]];
      double l1 = a[sel[2]];
      double l2 = a[sel[0]];
      double l3 = a[sel[3]];
      double x1 = (a0 * a0 + l2 * l2 - l1 * l1) / (2.0 * a0);
      double y1 =
          ((-2 * x0 * x1) + x0 * x0 + y0 * y0 + l2 * l2 - l3 * l3) / (2.0 * y0);
      double h = sqrt(l2 * l2 - (x1 * x1 + y1 * y1));
      double s = (a[sel[1]] + a[sel[4]] + a[sel[5]]) / 2.0;
      double S = sqrt(s * (s - a[sel[1]]) * (s - a[sel[4]]) * (s - a[sel[5]]));
      double V = (S * h) / 3.0;
      if (!EQ(opt, V) && opt < V)
        opt = V;
      // opt=max(opt,V);
    } while (next_permutation(sel, sel + 6));
  } else {
    // cur以降から選ぶ
    for (int i = cur; i < N; i++) {
      getNum[pos] = i;
      dfs(pos + 1, i + 1);
    }
  }
}

int main() {
  while (cin >> N && N) {
    memset(getNum, 0, sizeof(getNum));
    opt = -1;
    for (int i = 0; i < N; i++)
      cin >> a[i];
    dfs(0, 0);
    printf("%.10f\n", opt);
  }
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>

using namespace std;

int N;
int a[20];
double opt;
int getNum[20];
int sel[20];

const double EPS = (1e-10);
bool EQ(double a, double b) { return abs(a - b) < EPS; }

bool check(int *tmparry) {
  sort(tmparry, tmparry + 3);
  return (tmparry[2] < tmparry[0] + tmparry[1]);
}
void dfs(int pos, int cur) {
  if (pos == 6) {
    for (int i = 0; i < 6; i++)
      sel[i] = getNum[i];
    sort(sel, sel + 6);
    const int size = 3;
    const int plc[] = {1, 4, 5};
    const int plc2[] = {0, 2, 3};
    int comb = (1 << size) - 1;
    while (comb < (1 << 6)) {
      int x = comb & -comb, y = comb + x;
      comb = ((comb & ~y) / x >> 1) | y;
      int cnt = 0;
      for (int i = 0; i < 6; i++) {
        if ((comb >> i) & 1) {
          sel[plc[cnt++]] = getNum[i];
        }
      }
      cnt = 0;
      int tmp[3];
      for (int i = 0; i < 6; i++)
        if (!((comb >> i) & 1))
          tmp[cnt++] = getNum[i];
      sort(tmp, tmp + 3);
      // 6!通りの組み合わせをすべて試す
      do {
        for (int i = 0; i < 3; i++)
          sel[plc2[i]] = tmp[i];
        int tmparry[3];
        for (int i = 0; i < 3; i++)
          tmparry[i] = a[sel[i]];
        if (!check(tmparry))
          continue;
        tmparry[0] = a[sel[0]];
        tmparry[1] = a[sel[4]];
        tmparry[2] = a[sel[3]];
        if (!check(tmparry))
          continue;
        tmparry[0] = a[sel[2]];
        tmparry[1] = a[sel[5]];
        tmparry[2] = a[sel[3]];
        if (!check(tmparry))
          continue;
        tmparry[0] = a[sel[1]];
        tmparry[1] = a[sel[5]];
        tmparry[2] = a[sel[4]];
        if (!check(tmparry))
          continue;
        double theta = a[sel[1]] * a[sel[1]] + a[sel[4]] * a[sel[4]] -
                       a[sel[5]] * a[sel[5]];
        theta /= (2.0 * a[sel[1]] * a[sel[4]]);
        theta = acos(theta);
        double x0 = a[sel[4]] * cos(theta);
        double y0 = a[sel[4]] * sin(theta);
        double a0 = a[sel[1]];
        double l1 = a[sel[2]];
        double l2 = a[sel[0]];
        double l3 = a[sel[3]];
        double x1 = (a0 * a0 + l2 * l2 - l1 * l1) / (2.0 * a0);
        double y1 = ((-2 * x0 * x1) + x0 * x0 + y0 * y0 + l2 * l2 - l3 * l3) /
                    (2.0 * y0);
        double h = sqrt(l2 * l2 - (x1 * x1 + y1 * y1));
        double s = (a[sel[1]] + a[sel[4]] + a[sel[5]]) / 2.0;
        double S =
            sqrt(s * (s - a[sel[1]]) * (s - a[sel[4]]) * (s - a[sel[5]]));
        double V = (S * h) / 3.0;
        if (!EQ(opt, V) && opt < V)
          opt = V;
      } while (next_permutation(tmp, tmp + 3));
    }
  } else {
    // cur以降から選ぶ
    for (int i = cur; i < N; i++) {
      getNum[pos] = i;
      dfs(pos + 1, i + 1);
    }
  }
}

int main() {
  while (cin >> N && N) {
    memset(getNum, 0, sizeof(getNum));
    opt = -1;
    for (int i = 0; i < N; i++)
      cin >> a[i];
    dfs(0, 0);
    printf("%.10f\n", opt);
  }
  return 0;
}