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

#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

class Union_find {
private:
  vector<int> par;
  vector<int> rank;
  int n;

public:
  Union_find(int a) {
    n = a;
    for (int i = 0; i < n; i++) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
};

int chain[10002];

int no(int idx) {
  int c = 1;
  int p = idx - 1;
  int q = idx + 1;
  int res = 0;
  while (chain[p] == chain[idx]) {
    p--;
    c++;
  }
  while (chain[q] == chain[idx]) {
    q++;
    c++;
  }
  while (c >= 4) {
    res += c;
    c = 0;
    if (chain[q] != chain[p])
      return res;
    if (chain[q] == chain[p] && chain[p] == -1)
      return res;

    int org = chain[p];
    while (chain[p] == org) {
      p--;
      c++;
    }
    while (chain[q] == org) {
      q++;
      c++;
    }
  }
  return res;
}

int main(void) {
  int N;
  fill(chain, chain + 10002, -1);
  while (cin >> N && N) {
    int res = 0;
    REP(i, N) {
      cin >> chain[i + 1];
      chain[i + 1]--;
    }
    REP(i, N) {
      REP(j, 3) {
        int tmp = chain[i + 1];
        chain[i + 1] = j;
        res = max(res, no(i + 1));
        chain[i + 1] = tmp;
      }
    }
    cout << N - res << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>

#define INF_LL 9000000000000000000
#define INF 2000000000

#define REP(i, n) for (int i = 0; i < (n); i++)
#define FOR(i, a, b) for (int i = (a); i < (b); i++)

using namespace std;

typedef long long ll;
typedef pair<int, int> PII;

class Union_find {
private:
  vector<int> par;
  vector<int> rank;
  int n;

public:
  Union_find(int a) {
    n = a;
    for (int i = 0; i < n; i++) {
      par.push_back(i);
      rank.push_back(0);
    }
  }

  int find(int x) {
    if (par[x] == x) {
      return x;
    } else {
      return par[x] = find(par[x]);
    }
  }

  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y)
      return;

    if (rank[x] < rank[y]) {
      par[x] = y;
    } else {
      par[y] = x;
      if (rank[x] == rank[y])
        rank[x]++;
    }
  }

  bool same(int x, int y) { return find(x) == find(y); }
};

int chain(vector<int> c, int i) {
  int res = 1;
  for (int id = i - 1; id >= 0 && c[i] == c[id]; id--) {
    res++;
  }
  for (int id = i + 1; id < c.size() && c[i] == c[id]; id++) {
    res++;
  }
  return res;
}

int main(void) {
  vector<int> c;
  int res;
  int N;
  while (cin >> N && N) {
    res = N;
    REP(i, N) {
      int a;
      cin >> a;
      c.push_back(--a);
    }
    REP(i, c.size()) {
      REP(col, 3) {
        vector<int> c2(c);
        c2[i] = col;
        if (chain(c2, i) < 4)
          continue;

        int point = i;
        while (chain(c2, point) >= 4) {
          for (int id = point - 1; id >= 0 && c2[id] == c2[point]; id--) {
            c2[id] = -1;
          }
          for (int id = point + 1; id < c2.size() && c2[id] == c2[point];
               id++) {
            c2[id] = -1;
          }
          c2[point] = -1;
          vector<int> a;
          REP(j, c2.size()) {
            if (c2[j] != -1)
              a.push_back(c2[j]);
          }
          c2 = a;

          REP(j, c2.size()) {
            if (chain(c2, j) >= 4) {
              point = j;
              break;
            }
          }
        }
        res = min(res, (int)c2.size());
      }
    }
    cout << res << endl;
  }
}