Problem p00867 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define MAX_N 1005
typedef complex<double> P;
double eps = 1e-6;

P calc(P a, P b, P c, P d) {
  a -= d;
  b -= d;
  c -= d;
  return d + a + (b - a) * imag(a / c) / imag(a / c - b / c);
}

bool isParallel(P a, P b, P c, P d) {
  return (abs(imag((a - b) * conj(c - d))) < eps);
}

bool eq(P a, P b) { return (abs(a - b) < eps); }

int n;
P A[MAX_N], B[MAX_N];
int G[MAX_N][MAX_N];
int ans[10];
bool visited[MAX_N];
vector<int> vec;

int solve() {
  if (vec.size() == 1)
    return 1;
  int cnt1 = 0, cnt2 = 0, size = vec.size();
  for (int i = 0; i < size; i++) {
    for (int j = 0; j < i; j++) {
      if (G[vec[i]][vec[j]] == 1)
        cnt1++;
      if (G[vec[i]][vec[j]] == 2)
        cnt2++;
    }
  }

  //  cout<<cnt1<<' '<<cnt2<<' '<<size<<endl;
  P g = A[vec[0]];
  for (int i = 0; i < size; i++) {
    int id = vec[i];
    //    cout<<A[id]-g<<' '<<B[id]-g<<endl;
  }
  if (size == 3) {
    if (cnt1 == 2 && cnt2 == 0)
      return 7;
    return 4;

    //    if(cnt1==1&&cnt2==1)return 4;
    //    assert(0);
  }
  if (size == 4) {
    if (cnt1 == 4 && cnt2 == 0)
      return 0;
    if (cnt1 == 3 && cnt2 == 1)
      return 9;
    if (cnt1 == 2 && cnt2 == 1)
      return 3;
    return 3;
    //    assert(0);
  }
  if (size == 5) {
    if (cnt1 == 4 && cnt2 == 1)
      return 6;
    if (cnt1 == 4 && cnt2 == 2)
      return 8;
    if (cnt1 == 4 && cnt2 == 0) {
      for (int i = 0; i < size; i++) {
        int C = 0, D;
        for (int j = 0; j < size; j++) {
          if (i != j && G[vec[i]][vec[j]]) {
            C++;
            D = j;
          }
        }

        if (C == 1) {
          P cp = calc(A[vec[i]], B[vec[i]], A[vec[D]], B[vec[D]]);

          P from, to, prev;
          if (eq(cp, A[vec[i]]))
            prev = B[vec[i]], from = A[vec[i]];
          else if (eq(cp, B[vec[i]]))
            prev = A[vec[i]], from = B[vec[i]];
          // else assert(0);

          if (eq(cp, A[vec[D]]))
            to = B[vec[D]];
          else if (eq(cp, B[vec[D]]))
            to = A[vec[D]];
          //          else assert(0);

          P base = from - prev, target = to - prev;
          if (imag(target * conj(base)) < -eps)
            return 2;
          else if (imag(target * conj(base)) > eps)
            return 5;
          //          else assert(0);
        }
      }
    }
    return 2;
    assert(0);
  }
  return -1;
}

void dfs(int pos) {
  if (visited[pos])
    return;
  visited[pos] = true;
  vec.push_back(pos);
  for (int i = 0; i < n; i++)
    if (G[pos][i] != 0)
      dfs(i);
}
bool eq(double a, double b) { return (-eps < a - b && a - b < eps); }
bool onSegment(P a, P b, P c) {
  return eq(abs(a - b), abs(a - c) + abs(b - c));
}

int check(int si, int ti) {
  if (isParallel(A[si], B[si], A[ti], B[ti]))
    return 0;
  P k = calc(A[si], B[si], A[ti], B[ti]);
  int count = 3;
  if (eq(k, A[si]) || eq(k, B[si]))
    count--;
  if (eq(k, A[ti]) || eq(k, B[ti]))
    count--;
  if (onSegment(A[si], B[si], k) && onSegment(A[ti], B[ti], k))
    return count;
  return 0;
}

int main() {
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    memset(G, 0, sizeof(G));
    for (int i = 0; i < n; i++) {
      double ax, ay, bx, by;
      cin >> ax >> ay >> bx >> by;
      A[i] = P(ax, ay);
      B[i] = P(bx, by);
      for (int j = 0; j < i; j++) {
        G[i][j] = G[j][i] = check(i, j);
      }
    }
    memset(ans, 0, sizeof(ans));
    memset(visited, false, sizeof(visited));
    for (int i = 0; i < n; i++) {
      if (visited[i])
        continue;
      vec.clear();
      dfs(i);

      ans[solve()]++;
    }
    for (int i = 0; i < 10; i++) {
      if (i)
        cout << ' ';
      cout << ans[i];
    }
    cout << endl;
  }
  return true;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define MAX_N 1005
typedef complex<double> P;
double eps = 1e-6;

P calc(P a, P b, P c, P d) {
  a -= d;
  b -= d;
  c -= d;
  return d + a + (b - a) * imag(a / c) / imag(a / c - b / c);
}

bool isParallel(P a, P b, P c, P d) {
  return (abs(imag((a - b) * conj(c - d))) < eps);
}

bool eq(P a, P b) { return (abs(a - b) < eps); }

int n;
P A[MAX_N], B[MAX_N];
int G[MAX_N][MAX_N];
int ans[10];
bool visited[MAX_N];
vector<int> vec;

int solve() {
  if (vec.size() == 1)
    return 1;
  int cnt1 = 0, cnt2 = 0, size = vec.size();
  for (int i = 0; i < size; i++) {
    for (int j = 0; j < i; j++) {
      if (G[vec[i]][vec[j]] == 1)
        cnt1++;
      if (G[vec[i]][vec[j]] == 2)
        cnt2++;
    }
  }

  //  cout<<cnt1<<' '<<cnt2<<' '<<size<<endl;
  P g = A[vec[0]];
  for (int i = 0; i < size; i++) {
    int id = vec[i];
    //    cout<<A[id]-g<<' '<<B[id]-g<<endl;
  }
  if (size == 3) {
    if (cnt1 == 2 && cnt2 == 0)
      return 7;
    return 4;

    //    if(cnt1==1&&cnt2==1)return 4;
    //    assert(0);
  }
  if (size == 4) {
    if (cnt1 == 4 && cnt2 == 0)
      return 0;
    if (cnt1 == 3 && cnt2 == 1)
      return 9;
    if (cnt1 == 2 && cnt2 == 1)
      return 3;
    return 3;
    //    assert(0);
  }
  if (size == 5) {
    if (cnt1 == 4 && cnt2 == 1)
      return 6;
    if (cnt1 == 4 && cnt2 == 2)
      return 8;
    if (cnt1 == 4 && cnt2 == 0) {
      for (int i = 0; i < size; i++) {
        int C = 0, D;
        for (int j = 0; j < size; j++) {
          if (i != j && G[vec[i]][vec[j]]) {
            C++;
            D = j;
          }
        }

        if (C == 1) {
          P cp = calc(A[vec[i]], B[vec[i]], A[vec[D]], B[vec[D]]);

          P from, to, prev;
          if (eq(cp, A[vec[i]]))
            prev = B[vec[i]], from = A[vec[i]];
          else if (eq(cp, B[vec[i]]))
            prev = A[vec[i]], from = B[vec[i]];
          // else assert(0);

          if (eq(cp, A[vec[D]]))
            to = B[vec[D]];
          else if (eq(cp, B[vec[D]]))
            to = A[vec[D]];
          //          else assert(0);

          P base = from - prev, target = to - prev;
          if (imag(target * conj(base)) < -eps)
            return 2;
          else if (imag(target * conj(base)) > eps)
            return 5;
          //          else assert(0);
        }
      }
    }
    return 2;
    assert(0);
  }
  return -1;
}

void dfs(int pos) {
  if (visited[pos])
    return;
  visited[pos] = true;
  vec.push_back(pos);
  for (int i = 0; i < n; i++)
    if (G[pos][i] != 0)
      dfs(i);
}
bool eq(double a, double b) { return (-eps < a - b && a - b < eps); }
bool onSegment(P a, P b, P c) {
  return eq(abs(a - b), abs(a - c) + abs(b - c));
}

int check(int si, int ti) {
  if (isParallel(A[si], B[si], A[ti], B[ti]))
    return 0;
  P k = calc(A[si], B[si], A[ti], B[ti]);
  int count = 3;
  if (eq(k, A[si]) || eq(k, B[si]))
    count--;
  if (eq(k, A[ti]) || eq(k, B[ti]))
    count--;
  if (onSegment(A[si], B[si], k) && onSegment(A[ti], B[ti], k))
    return count;
  return 0;
}

int main() {
  while (1) {
    cin >> n;
    if (n == 0)
      break;
    memset(G, 0, sizeof(G));
    for (int i = 0; i < n; i++) {
      double ax, ay, bx, by;
      cin >> ax >> ay >> bx >> by;
      A[i] = P(ax, ay);
      B[i] = P(bx, by);
      for (int j = 0; j < i; j++) {
        G[i][j] = G[j][i] = check(i, j);
      }
    }
    memset(ans, 0, sizeof(ans));
    memset(visited, false, sizeof(visited));
    for (int i = 0; i < n; i++) {
      if (visited[i])
        continue;
      vec.clear();
      dfs(i);

      ans[solve()]++;
    }
    for (int i = 0; i < 10; i++) {
      if (i)
        cout << ' ';
      cout << ans[i];
    }
    cout << endl;
  }
  return 0;
}