Problem p01416 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
#define int long long // <-----!!!!!!!!!!!!!!!!!!!

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define rrep2(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(a) (a).begin(), (a).end()

typedef long long ll;
typedef pair<int, int> Pii;
typedef tuple<int, int, int> TUPLE;
typedef vector<int> V;
typedef vector<V> VV;
typedef vector<VV> VVV;
typedef vector<vector<int>> Graph;
const int inf = 1e9;
const int mod = 1e9 + 7;

enum { X, Y, CHAR };
typedef vector<int> Tile;

int H, W;
vector<string> s;

// N, E, S, W
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

inline bool inside(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }

Tile findNearestTile(int x, int y, int k) {
  if (!inside(x, y) || s[x][y] == '#')
    return Tile{-1, -1, -1};
  if (isalpha(s[x][y]))
    return Tile{x, y, s[x][y] - 'A'};
  return findNearestTile(x + dx[k], y + dy[k], k);
}

bool hit(int sx, int sy) {
  if (s[sx][sy] == '#')
    return false;
  if (isalpha(s[sx][sy])) {
    rep(k, 4) {
      int nx = sx + dx[k], ny = sy + dy[k];
      if (!inside(nx, ny))
        continue;
      if (s[sx][sy] == s[nx][ny]) {
        // cerr << "hey!" << endl;
        // cerr << sx << " " << sy << " " << nx << " " << ny << endl;
        // s[sx][sy] = '.';
        // s[nx][ny] = '.';
        return true;
      }
    }
    return false;
  }

  // cout << "hit: " << sx << " " << sy << endl;
  rep(start, 4) {
    Tile tile1{-1, -1, -1};
    rep(k, 4) {
      // cout << start << " " << k << endl;
      Tile tile2 = findNearestTile(sx, sy, (k + start) % 4);
      if (tile2[CHAR] == -1) {
        continue;
      } else if (tile1[CHAR] == -1) {
        tile1 = tile2;
      } else if (tile1[CHAR] == tile2[CHAR]) {
        // cout << sx << " " << sy << endl;
        // cout << start << " " << k << endl;
        // cout << tile1[X] << " " << tile1[Y] << " " << tile1[CHAR] << endl;
        // cout << tile2[X] << " " << tile2[Y] << " " << tile2[CHAR] << endl;
        s[tile1[X]][tile1[Y]] = '.';
        s[tile2[X]][tile2[Y]] = '.';
        return true;
      }
    }
  }
  return false;
}

bool search() {
  rep(i, H) {
    rep(j, W) {
      if (hit(i, j)) {
        // cout << "hit" << endl;
        // cout << i << " " << j << endl;
        return true;
      }
    }
  }
  return false;
}

bool checkCompress(string line) {
  for (const auto &c : line) {
    if (c != '.')
      return false;
  }
  return true;
}

void compress(vector<string> &s) {
  for (int i = 0; i < s.size();) {
    if (checkCompress(s[i])) {
      s.erase(s.begin() + i);
    } else {
      i++;
    }
  }
}

void rot(vector<string> &s) {
  vector<string> t(s[0].size(), "");
  rep(i, s.size()) rep(j, s[0].size()) { t[j] += s[i][j]; }
  s = t;
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  cin >> H >> W;
  s.resize(H);
  rep(i, H) cin >> s[i];

  rep(x, H) {
    rep(y, W) {
      rep(k, 4) {
        int nx = x + dx[k], ny = y + dy[k];
        if (!inside(nx, ny))
          continue;
        if (isalpha(s[x][y]) && s[x][y] == s[nx][ny]) {
          s[x][y] = '#';
          s[nx][ny] = '#';
        }
      }
    }
  }

  compress(s);
  // for (auto line : s) cout << line << endl;
  // cout << endl;

  if (s.empty()) {
    cout << 0 << endl;
    return 0;
  }
  rot(s);
  // // for (auto line : s) cout << line << endl;
  // // cout << endl;
  compress(s);
  // // for (auto line : s) cout << line << endl;
  // // cout << endl;
  rot(s);
  // // for (auto line : s) cout << line << endl;
  // // cout << endl;

  H = s.size(), W = s[0].size();

  int ans = 0;
  while (search()) {
    ans += 2;

    // cout << ans << endl;
    // rep(i, H) {
    //     cout << s[i] << endl;
    // }
    // cout << endl;
  }

  cout << ans << endl;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define int long long // <-----!!!!!!!!!!!!!!!!!!!

#define rep(i, n) for (int i = 0; i < (n); i++)
#define rep2(i, a, b) for (int i = (a); i < (b); i++)
#define rrep(i, n) for (int i = (n)-1; i >= 0; i--)
#define rrep2(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define all(a) (a).begin(), (a).end()

typedef long long ll;
typedef pair<int, int> Pii;
typedef tuple<int, int, int> TUPLE;
typedef vector<int> V;
typedef vector<V> VV;
typedef vector<VV> VVV;
typedef vector<vector<int>> Graph;
const int inf = 1e9;
const int mod = 1e9 + 7;

enum { X, Y, CHAR };
typedef vector<int> Tile;

int H, W;
vector<string> s;

// N, E, S, W
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

inline bool inside(int x, int y) { return 0 <= x && x < H && 0 <= y && y < W; }

Tile findNearestTile(int x, int y, int k) {
  if (!inside(x, y) || s[x][y] == '#')
    return Tile{-1, -1, -1};
  if (isalpha(s[x][y]))
    return Tile{x, y, s[x][y] - 'A'};
  return findNearestTile(x + dx[k], y + dy[k], k);
}

bool hit(int sx, int sy) {
  if (s[sx][sy] == '#')
    return false;
  if (isalpha(s[sx][sy])) {
    rep(k, 4) {
      int nx = sx + dx[k], ny = sy + dy[k];
      if (!inside(nx, ny))
        continue;
      if (s[sx][sy] == s[nx][ny]) {
        // cerr << "hey!" << endl;
        // cerr << sx << " " << sy << " " << nx << " " << ny << endl;
        s[sx][sy] = '.';
        s[nx][ny] = '.';
        return true;
      }
    }
    return false;
  }

  // cout << "hit: " << sx << " " << sy << endl;
  rep(start, 4) {
    Tile tile1{-1, -1, -1};
    rep(k, 4) {
      // cout << start << " " << k << endl;
      Tile tile2 = findNearestTile(sx, sy, (k + start) % 4);
      if (tile2[CHAR] == -1) {
        continue;
      } else if (tile1[CHAR] == -1) {
        tile1 = tile2;
      } else if (tile1[CHAR] == tile2[CHAR]) {
        // cout << sx << " " << sy << endl;
        // cout << start << " " << k << endl;
        // cout << tile1[X] << " " << tile1[Y] << " " << tile1[CHAR] << endl;
        // cout << tile2[X] << " " << tile2[Y] << " " << tile2[CHAR] << endl;
        s[tile1[X]][tile1[Y]] = '.';
        s[tile2[X]][tile2[Y]] = '.';
        return true;
      }
    }
  }
  return false;
}

bool search() {
  rep(i, H) {
    rep(j, W) {
      if (hit(i, j)) {
        // cout << "hit" << endl;
        // cout << i << " " << j << endl;
        return true;
      }
    }
  }
  return false;
}

bool checkCompress(string line) {
  for (const auto &c : line) {
    if (c != '.')
      return false;
  }
  return true;
}

void compress(vector<string> &s) {
  for (int i = 0; i < s.size();) {
    if (checkCompress(s[i])) {
      s.erase(s.begin() + i);
    } else {
      i++;
    }
  }
}

void rot(vector<string> &s) {
  vector<string> t(s[0].size(), "");
  rep(i, s.size()) rep(j, s[0].size()) { t[j] += s[i][j]; }
  s = t;
}

signed main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  cin >> H >> W;
  s.resize(H);
  rep(i, H) cin >> s[i];

  rep(x, H) {
    rep(y, W) {
      rep(k, 4) {
        int nx = x + dx[k], ny = y + dy[k];
        if (!inside(nx, ny))
          continue;
        if (isalpha(s[x][y]) && s[x][y] == s[nx][ny]) {
          s[x][y] = '#';
          s[nx][ny] = '#';
        }
      }
    }
  }

  compress(s);
  // for (auto line : s) cout << line << endl;
  // cout << endl;

  if (s.empty()) {
    cout << 0 << endl;
    return 0;
  }
  rot(s);
  // // for (auto line : s) cout << line << endl;
  // // cout << endl;
  compress(s);
  // // for (auto line : s) cout << line << endl;
  // // cout << endl;
  rot(s);
  // // for (auto line : s) cout << line << endl;
  // // cout << endl;

  H = s.size(), W = s[0].size();

  int ans = 0;
  while (search()) {
    ans += 2;

    // cout << ans << endl;
    // rep(i, H) {
    //     cout << s[i] << endl;
    // }
    // cout << endl;
  }

  cout << ans << endl;
}