Problem p01108 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <iostream>
#include <math.h>
#define eps 1e-9

using namespace std;

struct vec2d {
  double x, y;
  vec2d() {}
  vec2d(double x, double y) { this->x = x, this->y = y; }
  double add(double a, double b) {
    if (fabs(a + b) < eps * (fabs(a) + fabs(b)))
      return 0.0;
    return a + b;
  }
  vec2d operator+(vec2d ope) { return vec2d(add(x, ope.x), add(y, ope.y)); }
  vec2d operator-(vec2d ope) { return vec2d(add(x, -ope.x), add(y, -ope.y)); }
  vec2d operator*(double t) { return vec2d(x * t, y * t); }
  vec2d operator/(double t) { return vec2d(x / t, y / t); }
  double dot(vec2d ope) { return add(x * ope.x, y * ope.y); }
  double cross(vec2d ope) { return add(x * ope.y, -y * ope.x); }
  double norm() {
    double d2 = dot(*this);
    if (d2 > 0)
      return sqrt(d2);
    return 0.0;
  }
};

double distPP(vec2d p, vec2d q) { return (p - q).norm(); }

bool isOnL(vec2d p, vec2d q, vec2d x) { return (p - x).cross(q - x) == 0; }

bool valid;
vec2d getCrossP(vec2d p, vec2d q, vec2d r, vec2d s) {
  if ((q - p).cross(s - r) == 0) {
    valid = false;
    return vec2d();
  }
  valid = true;
  double t = (r - p).cross(s - r) / (q - p).cross(s - r);
  return p + (q - p) * t;
}

bool isSamePP(vec2d p, vec2d q) { return (distPP(p, q) < eps); }

vec2d p[3], q[3];

int dfs(vec2d p[], int cnt) {
  /*cout << cnt << " ";
  for(int i = 0; i < 3; i++){
          cout << "(" << p[i].x << ", " << p[i].y << ")";
  }
  cout << endl;*/

  bool matchP[3], matchQ[3];
  for (int i = 0; i < 3; i++)
    matchP[i] = matchQ[i] = false;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      if (matchQ[j])
        continue;
      if (isSamePP(p[i], q[j])) {
        matchP[i] = matchQ[j] = true;
        break;
      }
    }
  }
  bool same = true;
  for (int i = 0; i < 3; i++)
    same &= matchP[i];
  if (same)
    return 0;

  int dif = 0;
  for (int i = 0; i < 3; i++)
    dif += !matchP[i];
  if (dif > 4 - cnt)
    return 5;

  int ret = 5;

  vec2d np[3];
  for (int i = 0; i < 3; i++)
    np[i] = p[i];
  for (int i = 0; i < 3; i++) {
    if (matchP[i])
      continue;
    for (int j = 0; j < 3; j++) {
      if (matchQ[j])
        continue;
      // cout << i << " " << j << endl;
      if (isOnL(p[i], p[i] + (p[(i + 1) % 3] - p[(i + 2) % 3]), q[j])) {
        np[i] = q[j];
        ret = min(ret, dfs(np, cnt + 1) + 1);
        np[i] = p[i];
      } else {
        if (!matchP[(i + 1) % 3]) {
          np[(i + 1) % 3] = getCrossP(
              p[(i + 2) % 3], p[(i + 2) % 3] + (q[j] - p[i]) * 1e5,
              p[(i + 1) % 3], p[(i + 1) % 3] + (p[i] - p[(i + 2) % 3]) * 1e5);
          if (valid)
            ret = min(ret, dfs(np, cnt + 1) + 1);
          np[(i + 1) % 3] = p[(i + 1) % 3];
        }
        if (!matchP[(i + 2) % 3]) {
          np[(i + 2) % 3] = getCrossP(
              p[(i + 1) % 3], p[(i + 1) % 3] + (q[j] - p[i]) * 1e5,
              p[(i + 2) % 3], p[(i + 2) % 3] + (p[i] - p[(i + 1) % 3]) * 1e5);
          if (valid)
            ret = min(ret, dfs(np, cnt + 1) + 1);
          np[(i + 2) % 3] = p[(i + 2) % 3];
        }
      }
    }
  }
  return ret;
}

int main(void) {
  while (cin >> p[0].x) {
    for (int i = 0; i < 3; i++) {
      if (i != 0)
        cin >> p[i].x;
      cin >> p[i].y;
    }
    for (int i = 0; i < 3; i++) {
      cin >> q[i].x >> q[i].y;
    }

    int ans = dfs(p, 0);
    if (ans >= 5)
      cout << "Many" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <iostream>
#include <math.h>
#define eps 1e-9

using namespace std;

struct vec2d {
  double x, y;
  vec2d() {}
  vec2d(double x, double y) { this->x = x, this->y = y; }
  double add(double a, double b) {
    if (fabs(a + b) < eps * (fabs(a) + fabs(b)))
      return 0.0;
    return a + b;
  }
  vec2d operator+(vec2d ope) { return vec2d(add(x, ope.x), add(y, ope.y)); }
  vec2d operator-(vec2d ope) { return vec2d(add(x, -ope.x), add(y, -ope.y)); }
  vec2d operator*(double t) { return vec2d(x * t, y * t); }
  vec2d operator/(double t) { return vec2d(x / t, y / t); }
  double dot(vec2d ope) { return add(x * ope.x, y * ope.y); }
  double cross(vec2d ope) { return add(x * ope.y, -y * ope.x); }
  double norm() {
    double d2 = dot(*this);
    if (d2 > 0)
      return sqrt(d2);
    return 0.0;
  }
};

double distPP(vec2d p, vec2d q) { return (p - q).norm(); }

bool isOnL(vec2d p, vec2d q, vec2d x) { return (p - x).cross(q - x) == 0; }

bool valid;
vec2d getCrossP(vec2d p, vec2d q, vec2d r, vec2d s) {
  if ((q - p).cross(s - r) == 0) {
    valid = false;
    return vec2d();
  }
  valid = true;
  double t = (r - p).cross(s - r) / (q - p).cross(s - r);
  return p + (q - p) * t;
}

bool isSamePP(vec2d p, vec2d q) { return (distPP(p, q) < eps); }

vec2d p[3], q[3];

int dfs(vec2d p[], int cnt) {
  /*cout << cnt << " ";
  for(int i = 0; i < 3; i++){
          cout << "(" << p[i].x << ", " << p[i].y << ")";
  }
  cout << endl;*/

  bool matchP[3], matchQ[3];
  for (int i = 0; i < 3; i++)
    matchP[i] = matchQ[i] = false;
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
      if (matchQ[j])
        continue;
      if (isSamePP(p[i], q[j])) {
        matchP[i] = matchQ[j] = true;
        break;
      }
    }
  }
  bool same = true;
  for (int i = 0; i < 3; i++)
    same &= matchP[i];
  if (same)
    return 0;
  if (cnt >= 4)
    return 5;

  int ret = 5;

  vec2d np[3];
  for (int i = 0; i < 3; i++)
    np[i] = p[i];
  for (int i = 0; i < 3; i++) {
    if (matchP[i])
      continue;
    for (int j = 0; j < 3; j++) {
      if (matchQ[j])
        continue;
      // cout << i << " " << j << endl;
      if (isOnL(p[i], p[i] + (p[(i + 1) % 3] - p[(i + 2) % 3]), q[j])) {
        np[i] = q[j];
        ret = min(ret, dfs(np, cnt + 1) + 1);
        np[i] = p[i];
      } else {
        if (!matchP[(i + 1) % 3]) {
          np[(i + 1) % 3] = getCrossP(
              p[(i + 2) % 3], p[(i + 2) % 3] + (q[j] - p[i]) * 1e5,
              p[(i + 1) % 3], p[(i + 1) % 3] + (p[i] - p[(i + 2) % 3]) * 1e5);
          if (valid)
            ret = min(ret, dfs(np, cnt + 1) + 1);
          np[(i + 1) % 3] = p[(i + 1) % 3];
        }
        if (!matchP[(i + 2) % 3]) {
          np[(i + 2) % 3] = getCrossP(
              p[(i + 1) % 3], p[(i + 1) % 3] + (q[j] - p[i]) * 1e5,
              p[(i + 2) % 3], p[(i + 2) % 3] + (p[i] - p[(i + 1) % 3]) * 1e5);
          if (valid)
            ret = min(ret, dfs(np, cnt + 1) + 1);
          np[(i + 2) % 3] = p[(i + 2) % 3];
        }
      }
    }
  }
  return ret;
}

int main(void) {
  while (cin >> p[0].x) {
    for (int i = 0; i < 3; i++) {
      if (i != 0)
        cin >> p[i].x;
      cin >> p[i].y;
    }
    for (int i = 0; i < 3; i++) {
      cin >> q[i].x >> q[i].y;
    }

    int ans = dfs(p, 0);
    if (ans >= 5)
      cout << "Many" << endl;
    else
      cout << ans << endl;
  }
  return 0;
}