Problem p00896 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;

char w1[22][110];
char w2[44][110];
int w1_cnt, w2_cnt;
int cw[28];
int aw[28];
bool ok[44][22];
int ok_cnt[44];
bool vis[44];
int ans;

bool cal_ok(int i, int j) {
  if (strlen(w2[i]) != strlen(w1[j]))
    return false;
  int tw[28];
  memcpy(tw, cw, sizeof(tw));
  for (int k = 0; w2[i][k]; k++) {
    int c = w2[i][k] - 'A';
    int d = w1[j][k] - 'A';
    if (tw[c] != -1 && tw[c] != w1[j][k])
      return false;
    if (tw[d] != -1 && tw[d] != w2[i][k])
      return false;
    tw[c] = w1[j][k];
    tw[d] = w2[i][k];
  }
  return true;
}
void get_ok() {
  memset(ok, 0, sizeof(ok));
  for (int i = 0; i < w2_cnt; i++)
    for (int j = 0; j < w1_cnt; j++) {
      ok[i][j] = cal_ok(i, j);
      if (ok[i][j])
        ok_cnt[i]++;
    }
}
void print_ok() {
  for (int i = 0; i < w2_cnt; i++) {
    for (int j = 0; j < w1_cnt; j++) {
      printf("%d ", ok[i][j]);
    }
    puts("");
  }
}

int find() {
  int p = -1;
  for (int i = 0; i < w2_cnt; i++)
    if (!vis[i])
      if (p == -1 || ok_cnt[i] < ok_cnt[p])
        p = i;
  return p;
}

void dfs(int u) {
  if (ans > 1)
    return;
  if (u == -1) {
    ans++;
    memcpy(aw, cw, sizeof(aw));
    return;
  }
  //    bool tmp[44][22];
  //    int tmp_cnt[44];
  int tw[28];
  //    memcpy(tmp, ok, sizeof(tmp));
  //    memcpy(tmp_cnt, ok_cnt, sizeof(ok_cnt));
  memcpy(tw, cw, sizeof(tw));
  get_ok();
  for (int i = 0; i < w1_cnt; i++)
    if (ok[u][i]) {
      vis[u] = true;
      for (int j = 0; w2[u][j]; j++) {
        int c = w2[u][j] - 'A';
        int d = w1[i][j] - 'A';
        cw[c] = w1[i][j];
        cw[d] = w2[u][j];
      }
      dfs(find());
      memcpy(cw, tw, sizeof(tw));
      vis[u] = false;
      get_ok();
      //        memcpy(ok_cnt, tmp_cnt, sizeof(tmp_cnt));
      //        memcpy(ok, tmp, sizeof(tmp));
    }
}

void work() {
  for (int i = 0; i < w1_cnt; i++)
    scanf("%s", w1[i]);
  w2_cnt = 0;
  while (true) {
    char str[100];
    scanf("%s", str);
    int len = strlen(str);
    if (str[len - 1] == '.') {
      str[--len] = 0;
      strcpy(w2[w2_cnt], str);
      w2_cnt++;
      break;
    } else {
      strcpy(w2[w2_cnt], str);
      w2_cnt++;
    }
  }
  // for (int i = 0; i < w2_cnt; i++) printf("%s ", w2[i]); puts(".....");
  memset(cw, -1, sizeof(cw));
  get_ok();
  // print_ok();
  memset(vis, 0, sizeof(vis));
  int p = find();
  // printf("%d\\n", p);
  ans = 0;
  dfs(p);
  if (ans > 1) {
    puts("-.");
    return;
  }
  // for (int i = 0; i < 26; i++) printf("%d ", aw[i]); puts("?");
  for (int i = 0; i < w2_cnt; i++) {
    for (int j = 0; w2[i][j]; j++) {
      int d = w2[i][j] - 'A';
      printf("%c", aw[d]);
    }
    if (i < w2_cnt - 1)
      printf(" ");
  }
  puts(".");
}

int main() {
  while (scanf("%d", &w1_cnt), w1_cnt) {
    work();
  }
  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#define FI first
#define SE second
using namespace std;
const double EPS = 1e-10;
const int MAXN = 5005;
const int INF = 1111111111;
const double PI = acos(-1.0);
typedef long long LL;
int dcmp(double x) {
  if (fabs(x) < EPS)
    return 0;
  return x < 0 ? -1 : 1;
}
struct Point {
  double x, y;
  void input() { scanf("%lf%lf", &x, &y); }
} p[MAXN];

bool cmp(double a, double b) { return dcmp(a - b) < 0; }
double ang[MAXN];
int main() {
  // freopen("/home/qitaishui/code/in.txt","r",stdin);
  int n;
  int ca;
  LL ans, sub, tri;
  scanf("%d", &ca);
  while (ca--) {
    sub = 0;
    scanf("%d", &n);
    ans = (LL)n * (n - 1) * (n - 2) * (n - 3) / 24;
    tri = (n - 1) * (n - 2) * (n - 3) / 6;
    for (int i = 0; i < n; i++)
      p[i].input();
    int m;
    for (int i = 0; i < n; i++) {
      m = 0;
      for (int j = 0; j < n; j++) {
        if (i == j)
          continue;
        ang[m++] = atan2(p[j].y - p[i].y, p[j].x - p[i].x);
      }
      sort(ang, ang + m, cmp);
      for (int i = 0; i < m; i++)
        ang[i + m] = 2 * PI + ang[i];
      int l, r, s;
      s = l = 0;
      r = 1;
      tri = (n - 1) * (n - 2) * (n - 3) / 6;
      while (l < m) {
        while (dcmp(ang[l] + PI - ang[r]) >= 0)
          r++, s++;
        if (s >= 2)
          tri -= (s - 1) * s / 2;
        s--;
        l++;
      }
      sub += tri;
    }
    cout << ans - sub << endl;
  }
  return 0;
}