Problem p00749 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define repr(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define rep(i, n) repl(i, 0, n)
#define each(itr, v) for (auto itr : v)
#define pb(s) push_back(s)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x " = " << x << endl
#define print(x) cout << x << endl
#define maxch(x, y) x = max(x, y)
#define minch(x, y) x = min(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt(x) bitset<32>(x).count()

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, int> PD;
typedef pair<P, int> PPI;
typedef pair<int, P> PIP;
typedef pair<ll, ll> PL;
typedef pair<P, ll> PPL;
typedef set<int> S;

#define INF INT_MAX / 3
#define MAX_N 1000000001

struct Piece {
  double gx;
  int xl, xr;
};

int w, h;
string s[60];
int dd[] = {1, 0, -1, 0, 1};
int on[100][100];
bool visited[60][10];
int panel[60][10];
Piece v[60];
bool stable;
double gx;
int num;

bool range(int x, int y) { return 0 <= x && x < w && 0 <= y && y < h; }

void search(int y, int x, char c, int num) {
  panel[y][x] = num;
  visited[y][x] = true;
  v[num].gx += x + 0.5;

  if (y == h - 1)
    minch(v[num].xl, x), maxch(v[num].xr, x + 1);

  rep(i, 4) {
    int yy = y + dd[i], xx = x + dd[i + 1];
    if (range(xx, yy) && s[yy][xx] == c && !visited[yy][xx]) {
      search(yy, xx, c, num);
    }
  }
}

void on_search(int y, int x, int num) {
  visited[y][x] = true;

  rep(i, 4) {
    int yy = y + dd[i], xx = x + dd[i + 1];
    if (range(xx, yy)) {
      if (i == 2 && panel[yy][xx] != num && panel[yy][xx] >= 0)
        on[num][panel[yy][xx]] = 1;
      if (i == 0 && panel[yy][xx] != num && panel[yy][xx] >= 0) {
        minch(v[num].xl, x), maxch(v[num].xr, x + 1);
      }
      if (!visited[yy][xx] && panel[yy][xx] == num)
        on_search(yy, xx, num);
    }
  }
}

void calc(int i, int size) {
  gx += v[i].gx, num++;
  rep(j, size) if (on[i][j]) calc(j, size);
}

bool centerGrabity(int i, int size) {
  gx = num = 0;
  calc(i, size);
  double g = gx / (num * 4);
  return (v[i].xl < g && g < v[i].xr);
}

int main() {
  cin.sync_with_stdio(false);
  while (cin >> w >> h, w | h) {
    rep(i, h) cin >> s[i];
    rep(i, h) rep(j, w) panel[i][j] = -1, visited[i][j] = false;
    rep(i, 100) rep(j, 100) on[i][j] = 0;

    int idx = 0;
    repr(i, h) {
      rep(j, w) {
        if (s[i][j] != '.' && panel[i][j] == -1) {
          Piece p = Piece{0.0, INF, -1};
          v[idx] = p;
          search(i, j, s[i][j], idx);
          idx++;
        }
      }
    }

    rep(i, h) rep(j, w) visited[i][j] = false;
    rep(i, h) rep(j, w) if (s[i][j] != '.' && !visited[i][j])
        on_search(i, j, panel[i][j]);

    stable = true;
    rep(i, idx) stable &= centerGrabity(i, idx);
    cout << ((stable) ? "STABLE" : "UNSTABLE") << endl;
  }

  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define repl(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define repr(i, n) for (int i = (int)(n - 1); i >= 0; i--)
#define rep(i, n) repl(i, 0, n)
#define each(itr, v) for (auto itr : v)
#define pb(s) push_back(s)
#define all(x) (x).begin(), (x).end()
#define dbg(x) cout << #x " = " << x << endl
#define print(x) cout << x << endl
#define maxch(x, y) x = max(x, y)
#define minch(x, y) x = min(x, y)
#define uni(x) x.erase(unique(all(x)), x.end())
#define exist(x, y) (find(all(x), y) != x.end())
#define bcnt(x) bitset<32>(x).count()

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> P;
typedef pair<double, int> PD;
typedef pair<P, int> PPI;
typedef pair<int, P> PIP;
typedef pair<ll, ll> PL;
typedef pair<P, ll> PPL;
typedef set<int> S;

#define INF INT_MAX / 3
#define MAX_N 1000000001

struct Piece {
  double gx;
  int xl, xr;
};

int w, h;
string s[60];
int dd[] = {1, 0, -1, 0, 1};
int on[100][100];
bool visited[60][10];
int panel[60][10];
Piece v[100];
bool stable;
double gx;
int num;

bool range(int x, int y) { return 0 <= x && x < w && 0 <= y && y < h; }

void search(int y, int x, char c, int num) {
  panel[y][x] = num;
  visited[y][x] = true;
  v[num].gx += x + 0.5;

  if (y == h - 1)
    minch(v[num].xl, x), maxch(v[num].xr, x + 1);

  rep(i, 4) {
    int yy = y + dd[i], xx = x + dd[i + 1];
    if (range(xx, yy) && s[yy][xx] == c && !visited[yy][xx]) {
      search(yy, xx, c, num);
    }
  }
}

void on_search(int y, int x, int num) {
  visited[y][x] = true;

  rep(i, 4) {
    int yy = y + dd[i], xx = x + dd[i + 1];
    if (range(xx, yy)) {
      if (i == 2 && panel[yy][xx] != num && panel[yy][xx] >= 0)
        on[num][panel[yy][xx]] = 1;
      if (i == 0 && panel[yy][xx] != num && panel[yy][xx] >= 0) {
        minch(v[num].xl, x), maxch(v[num].xr, x + 1);
      }
      if (!visited[yy][xx] && panel[yy][xx] == num)
        on_search(yy, xx, num);
    }
  }
}

void calc(int i, int size) {
  gx += v[i].gx, num++;
  rep(j, size) if (on[i][j]) calc(j, size);
}

bool centerGrabity(int i, int size) {
  gx = num = 0;
  calc(i, size);
  double g = gx / (num * 4);
  return (v[i].xl < g && g < v[i].xr);
}

int main() {
  cin.sync_with_stdio(false);
  while (cin >> w >> h, w | h) {
    rep(i, h) cin >> s[i];
    rep(i, h) rep(j, w) panel[i][j] = -1, visited[i][j] = false;
    rep(i, 100) rep(j, 100) on[i][j] = 0;

    int idx = 0;
    repr(i, h) {
      rep(j, w) {
        if (s[i][j] != '.' && panel[i][j] == -1) {
          Piece p = Piece{0.0, INF, -1};
          v[idx] = p;
          search(i, j, s[i][j], idx);
          idx++;
        }
      }
    }

    rep(i, h) rep(j, w) visited[i][j] = false;
    rep(i, h) rep(j, w) if (s[i][j] != '.' && !visited[i][j])
        on_search(i, j, panel[i][j]);

    stable = true;
    rep(i, idx) stable &= centerGrabity(i, idx);
    cout << ((stable) ? "STABLE" : "UNSTABLE") << endl;
  }

  return 0;
}