Problem p03968 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <iostream>
#include <map>

using namespace std;

long long calc(int a, int b, int c, int d) {
  long long r = 1024 * a + b;
  r = 1024 * r + c;
  return 1024 * r + d;
}

long long pack(int a, int b, int c, int d) {
  return min(min(calc(a, b, c, d), calc(b, c, d, a)),
             min(calc(c, d, a, b), calc(d, a, b, c)));
}

int getR(long long key) {
  int c[4];
  for (int i = 0; i < 4; i++) {
    c[i] = key % 1024;
    key /= 1024;
  }
  if (c[0] == c[1] && c[1] == c[2] && c[2] == c[3])
    return 4;
  if (c[0] == c[2] && c[1] == c[3])
    return 2;
  return 1;
}

long long pow(int a, int p) {
  long long r = 1;
  for (int i = 0; i < p; i++)
    r *= a;
  return r;
}

long long fact(int f) {
  long long r = 1;
  for (int i = 2; i <= f; i++)
    r *= i;
  return r;
}

int main() {
  int N;
  static int c[400][4];
  static long long comb[400][400];
  comb[1][0] = comb[1][1] = 1;
  for (int i = 2; i <= 400; i++) {
    comb[i][0] = 1;
    for (int j = 1; j < i; j++)
      comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
    comb[i][i] = 1;
  }
  while (cin >> N && N) {
    map<long long, int> num;
    long long res = 0;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 4; j++)
        cin >> c[i][j];
      for (int j = 0; j < i; j++) {
        const int *back = c[j];
        for (int k = 0; k < 4; k++) {
          long long key[4];
          key[0] = pack(back[(k + 1) % 4], back[(k + 0) % 4], c[i][1], c[i][0]);
          key[1] = pack(back[(k + 0) % 4], back[(k + 3) % 4], c[i][2], c[i][1]);
          key[2] = pack(back[(k + 3) % 4], back[(k + 2) % 4], c[i][3], c[i][2]);
          key[3] = pack(back[(k + 2) % 4], back[(k + 1) % 4], c[i][0], c[i][3]);
          sort(key, key + 4);
          long long backKey = pack(back[0], back[1], back[2], back[3]);
          long long add = 1;
          for (int l = 0; l < 4;) {
            int cnt = 1;
            for (int m = l + 1; m < 4 && key[l] == key[m]; m++)
              ++cnt;
            int sel = 0;
            if (num.count(key[l]))
              sel = num[key[l]];
            if (key[l] == backKey)
              --sel;
            if (sel < cnt) {
              add = 0;
              break;
            }
            add *= comb[sel][cnt] * pow(getR(key[l]), cnt) * fact(cnt);
            l += cnt;
          }
          res += add;
        }
      }
      long long k = pack(c[i][0], c[i][1], c[i][2], c[i][3]);
      if (num.count(k))
        ++num[k];
      else
        num[k] = 1;
    }
    cout << res << endl;
  }
}


Fixed submission:
#include <algorithm>
#include <iostream>
#include <map>

using namespace std;

long long calc(int a, int b, int c, int d) {
  long long r = 1024 * a + b;
  r = 1024 * r + c;
  return 1024 * r + d;
}

long long pack(int a, int b, int c, int d) {
  return min(min(calc(a, b, c, d), calc(b, c, d, a)),
             min(calc(c, d, a, b), calc(d, a, b, c)));
}

int getR(long long key) {
  int c[4];
  for (int i = 0; i < 4; i++) {
    c[i] = key % 1024;
    key /= 1024;
  }
  if (c[0] == c[1] && c[1] == c[2] && c[2] == c[3])
    return 4;
  if (c[0] == c[2] && c[1] == c[3])
    return 2;
  return 1;
}

long long pow(int a, int p) {
  long long r = 1;
  for (int i = 0; i < p; i++)
    r *= a;
  return r;
}

long long fact(int f) {
  long long r = 1;
  for (int i = 2; i <= f; i++)
    r *= i;
  return r;
}

int main() {
  int N;
  static int c[400][4];
  static long long comb[400][401];
  comb[1][0] = comb[1][1] = 1;
  for (int i = 2; i <= 400; i++) {
    comb[i][0] = 1;
    for (int j = 1; j < i; j++)
      comb[i][j] = comb[i - 1][j - 1] + comb[i - 1][j];
    comb[i][i] = 1;
  }
  while (cin >> N && N) {
    map<long long, int> num;
    long long res = 0;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 4; j++)
        cin >> c[i][j];
      for (int j = 0; j < i; j++) {
        const int *back = c[j];
        for (int k = 0; k < 4; k++) {
          long long key[4];
          key[0] = pack(back[(k + 1) % 4], back[(k + 0) % 4], c[i][1], c[i][0]);
          key[1] = pack(back[(k + 0) % 4], back[(k + 3) % 4], c[i][2], c[i][1]);
          key[2] = pack(back[(k + 3) % 4], back[(k + 2) % 4], c[i][3], c[i][2]);
          key[3] = pack(back[(k + 2) % 4], back[(k + 1) % 4], c[i][0], c[i][3]);
          sort(key, key + 4);
          long long backKey = pack(back[0], back[1], back[2], back[3]);
          long long add = 1;
          for (int l = 0; l < 4;) {
            int cnt = 1;
            for (int m = l + 1; m < 4 && key[l] == key[m]; m++)
              ++cnt;
            int sel = 0;
            if (num.count(key[l]))
              sel = num[key[l]];
            if (key[l] == backKey)
              --sel;
            if (sel < cnt) {
              add = 0;
              break;
            }
            add *= comb[sel][cnt] * pow(getR(key[l]), cnt) * fact(cnt);
            l += cnt;
          }
          res += add;
        }
      }
      long long k = pack(c[i][0], c[i][1], c[i][2], c[i][3]);
      if (num.count(k))
        ++num[k];
      else
        num[k] = 1;
    }
    cout << res << endl;
  }
}