Problem p01127 (C++) — buggy submission, verdict: Runtime Error

using namespace std; /*{{{*/

#include <iostream>
#include <map>
#include <vector>

typedef vector<char> VC;
typedef vector<VC> VVC;

#define FOR(i, b, e) for (typeof(e) i = (b); i != (e); i < (e) ? ++i : --i)
#define REP(i, n) FOR(i, 0, n)

#define EACH(c, it)                                                            \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define EXIST(s, e) ((s).find(e) != (s).end())
/*}}}*/

struct article {
  char material;
  bool is_removed;
  int topmost;
  int bottommost;
  int leftmost;
  int rightmost;
};

typedef map<char, article> MCA;

VVC image;
MCA articles;

bool remove_all() {
  bool all_removed = true;
  EACH(articles, itr) {
    article &art = itr->second;
    if (!art.is_removed) {
      all_removed = false;
      // Remove it and recurse
      VVC save = image;
      bool rect = true;
      FOR(i, art.topmost, art.bottommost + 1) {
        FOR(j, art.leftmost, art.rightmost + 1) {
          if (image[i][j] != '*' && image[i][j] != art.material) {
            rect = false;
          } else {
            image[i][j] = '*';
          }
        }
      }
      if (rect) {
        // Recurse
        art.is_removed = true;
        if (remove_all()) {
          return true;
        }
      }
      // Restore and continue trying
      art.is_removed = false;
      image = save;
    }
  }
  return all_removed;
}

int main() {
  int t;
  cin >> t;
  REP(_, t) {
    // Initialize
    articles.clear();

    int h, w;
    cin >> h >> w;
    image = VVC(h, VC(w, '.'));
    REP(i, h) {
      REP(j, w) { cin >> image[i][j]; }
    }

    // Scan Image
    REP(i, h) {
      REP(j, w) {
        if (image[i][j] != '.') {
          char c = image[i][j];
          if (!EXIST(articles, c)) {
            article a = {c, false, 50, 0, 50, 0};
            articles[c] = a;
          }
          articles[c].topmost = min(articles[c].topmost, i);
          articles[c].bottommost = max(articles[c].bottommost, i);
          articles[c].leftmost = min(articles[c].leftmost, j);
          articles[c].rightmost = max(articles[c].rightmost, j);
        }
      }
    }

    if (remove_all()) {
      cout << "SAFE" << endl;
    } else {
      cout << "SUSPICIOUS" << endl;
    }
  }
}

// vim: foldmethod=marker

Error: WA

Fixed submission:

using namespace std; /*{{{*/

#include <iostream>
#include <map>
#include <vector>

typedef vector<char> VC;
typedef vector<VC> VVC;

#define FOR(i, b, e) for (typeof(e) i = (b); i != (e); i < (e) ? ++i : --i)
#define REP(i, n) FOR(i, 0, n)

#define EACH(c, it)                                                            \\
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define EXIST(s, e) ((s).find(e) != (s).end())
/*}}}*/

struct article {
  char material;
  bool is_removed;
  int topmost;
  int bottommost;
  int leftmost;
  int rightmost;
};

typedef map<char, article> MCA;

VVC image;
MCA articles;

bool remove_all() {
  bool all_removed = true;
  EACH(articles, itr) {
    article &art = itr->second;
    if (!art.is_removed) {
      all_removed = false;
      // Remove it and recurse
      VVC save = image;
      bool rect = true;
      FOR(i, art.topmost, art.bottommost + 1) {
        FOR(j, art.leftmost, art.rightmost + 1) {
          if (image[i][j] != '*' && image[i][j] != art.material) {
            rect = false;
          } else {
            image[i][j] = '*';
          }
        }
      }
      if (rect) {
        // Recurse
        art.is_removed = true;
        if (remove_all()) {
          return true;
        }
      }
      // Restore and continue trying
      art.is_removed = false;
      image = save;
    }
  }
  return all_removed;
}

int main() {
  int t;
  cin >> t;
  REP(_, t) {
    int h, w;
    cin >> h >> w;
    image = VVC(h, VC(w, '.'));
    REP(i, h) {
      REP(j, w) { cin >> image[i][j]; }
    }

    // Scan Image
    REP(i, h) {
      REP(j, w) {
        if (image[i][j] != '.') {
          char c = image[i][j];
          if (!EXIST(articles, c)) {
            article a = {c, false, h - 1, 0, w - 1, 0};
            articles[c] = a;
          }
          articles[c].topmost = min(articles[c].topmost, i);
          articles[c].bottommost = max(articles[c].bottommost, i);
          articles[c].leftmost = min(articles[c].leftmost, j);
          articles[c].rightmost = max(articles[c].rightmost, j);
        }
      }
    }

    if (remove_all()) {
      cout << "SAFE" << endl;
    } else {
      cout << "SUSPICIOUS" << endl;
    }
  }
}

// vim: foldmethod=marker