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

#include <bits/stdc++.h>
#define EPS (1e-8)
#define INF (1e9)
#define X real()
#define Y imag()
#define N 105
#define M 15
using namespace std;
typedef pair<string, string> P1;
typedef complex<double> P;
int n, a, b, Slen, mark[M], ans;
vector<P> v[N];
set<string> S;
string s[N];
string d[M];
set<P1> z;

double dot(P A, P B) { return real(conj(A) * B); }
double cross(P A, P B) { return imag(conj(A) * B); }

int ccw(P A, P B, P C) {
  B -= A;
  C -= A;
  if (cross(B, C) > EPS)
    return 1;
  if (cross(B, C) < -EPS)
    return -1;
  if (dot(B, C) < -EPS)
    return 2;
  if (norm(B) < norm(C))
    return -2;
  return 0;
}

bool check(P A1, P A2, P B1, P B2) {
  int r1 = ccw(A1, A2, B1);
  int r2 = ccw(A1, A2, B2);
  int r3 = ccw(B1, B2, A1);
  int r4 = ccw(B1, B2, A2);
  if (r1 == 1 || r1 == -1 || r2 == 1 || r2 == -1)
    return false;
  A2 -= A1, B1 -= A1, B2 -= A1, A1 -= A1;
  B1 = B1 * conj(A2) / abs(A2);
  B2 = B2 * conj(A2) / abs(A2);
  A2 = A2 * conj(A2) / abs(A2);
  if (A1.X > A2.X)
    swap(A1, A2);
  if (B1.X > B2.X)
    swap(B1, B2);
  double left = max(A1.X, B1.X);
  double right = min(A2.X, B2.X);
  if (right - left <= EPS)
    return false;
  if (!r1 || !r2 || !r3 || !r4)
    return true;
  return false;
}

void func(int x) {
  for (int i = 0; i < x; i++) {
    for (int j = i + 1; j < x; j++) {
      if (mark[i] != mark[j])
        continue;
      string s1 = min(d[i], d[j]);
      string s2 = max(d[i], d[j]);
      if (z.find(P1(s1, s2)) != z.end())
        return;
    }
  }
  if (x == Slen) {
    set<int> cnt;
    for (int i = 0; i < Slen; i++)
      cnt.insert(mark[i]);
    ans = min(ans, (int)cnt.size());
    return;
  }
  for (int i = 0; i <= x; i++)
    mark[x] = i, func(x + 1);
}

int main() {
  while (1) {
    cin >> n;
    if (!n)
      break;
    for (int i = 0; i < n; i++) {
      cin >> s[i];
      S.insert(s[i]);
      while (1) {
        cin >> a;
        if (a < 0)
          break;
        cin >> b;
        v[i].push_back(P(a, b));
      }
    }
    Slen = S.size();
    set<string>::iterator ite;
    int k = 0;
    for (ite = S.begin(); ite != S.end(); ite++, k++)
      d[k] = (*ite);
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        int leni = v[i].size();
        int lenj = v[j].size();
        string s1 = s[i], s2 = s[j];
        if (s1 == s2)
          continue;
        if (s1 > s2)
          swap(s1, s2);
        for (int k = 0; k < leni; k++)
          for (int l = 0; l < lenj; l++) {
            P A1 = v[i][k], A2 = v[i][(k + 1) % leni];
            P B1 = v[j][l], B2 = v[j][(l + 1) % lenj];
            if (check(A1, A2, B1, B2))
              z.insert(P1(s1, s2));
          }
      }
    }
    ans = INF;
    func(0);
    cout << ans << endl;
    for (int i = 0; i < n; i++)
      v[i].clear();
    S.clear();
    z.clear();
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define EPS (1e-8)
#define INF (1e9)
#define X real()
#define Y imag()
#define N 100
#define M 10
using namespace std;
typedef pair<string, string> P1;
typedef complex<double> P;
int n, a, b, Slen, mark[M], ans;
vector<P> v[N];
set<string> S;
string s[N];
set<P1> z;
string d[M];

bool eq(double n1, double n2) { return abs(n1 - n2) < EPS; }

double cross(P pa, P pb) { return imag(conj(pa) * pb); }

bool check(P A1, P A2, P B1, P B2) {
  bool r = false;
  double Alen = abs(A2 - A1);
  double Blen = abs(B2 - B1);
  A2 -= A1, B1 -= A1, B2 -= A1, A1 -= A1;
  B1 = B1 * conj(A2) / abs(A2);
  B2 = B2 * conj(A2) / abs(A2);
  A2 = A2 * conj(A2) / abs(A2);
  double Xmin = min(min(A1.X, A2.X), min(B1.X, B2.X));
  double Xmax = max(max(A1.X, A2.X), max(B1.X, B2.X));
  if (A1.X <= B1.X && B1.X <= A2.X)
    r = true;
  if (A1.X <= B2.X && B2.X <= A2.X)
    r = true;
  if (B1.X <= A2.X && A2.X <= B2.X)
    r = true;
  if (B1.X <= A1.X && A1.X <= B2.X)
    r = true;
  double l = abs(Xmin - Xmax);
  if (eq(l, Alen + Blen))
    r = false;
  if (!eq(B1.Y, 0) || !eq(B2.Y, 0))
    r = false;
  return r;
}

void func(int x) {
  if (x == Slen) {
    set<string>::iterator ite;
    int f = 0;
    for (int i = 0; i < Slen; i++) {
      for (int j = i + 1; j < Slen; j++) {
        if (mark[i] != mark[j])
          continue;
        if (z.find(P1(d[i], d[j])) != z.end())
          f = 1;
      }
    }
    if (!f) {
      set<int> cnt;
      for (int i = 0; i < Slen; i++)
        cnt.insert(mark[i]);
      ans = min(ans, (int)cnt.size());
    }
    return;
  }
  for (int i = 0; i <= x; i++)
    mark[x] = i, func(x + 1);
}

int main() {
  while (1) {
    cin >> n;
    if (!n)
      break;
    for (int i = 0; i < n; i++) {
      cin >> s[i];
      S.insert(s[i]);
      while (1) {
        cin >> a;
        if (a < 0)
          break;
        cin >> b;
        v[i].push_back(P(a, b));
      }
    }
    Slen = S.size();
    set<string>::iterator ite;
    int k = 0;
    for (ite = S.begin(); ite != S.end(); ite++, k++)
      d[k] = (*ite);
    for (int i = 0; i < n; i++) {
      for (int j = i + 1; j < n; j++) {
        int leni = v[i].size();
        int lenj = v[j].size();
        string s1 = s[i], s2 = s[j];
        if (s1 == s2)
          continue;
        if (s1 > s2)
          swap(s1, s2);
        for (int k = 0; k < leni; k++)
          for (int l = 0; l < lenj; l++) {
            P pa1 = v[i][k], pa2 = v[i][(k + 1) % leni];
            P pb1 = v[j][l], pb2 = v[j][(l + 1) % lenj];
            if (check(pa1, pa2, pb1, pb2))
              z.insert(P1(s1, s2));
          }
      }
    }
    ans = INF;
    func(0);
    cout << ans << endl;
    for (int i = 0; i < n; i++)
      v[i].clear();
    S.clear();
    z.clear();
  }
  return 0;
}