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

// Is input file is the same as the below link?
// http://acm-icpc.aitea.net/index.php?plugin=attach&refer=2006%2FPractice%2F%CC%CF%B5%BC%B9%F1%C6%E2%CD%BD%C1%AA%2F%CC%E4%C2%EA%CA%B8%A4%C8%A5%C7%A1%BC%A5%BF%A5%BB%A5%C3%A5%C8&openfile=judge-data.zip
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <vector>

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define sz size()
#define pb push_back
#define mp make_pair
#define ALL(X) (X).begin(), (X).end()

using namespace std;

const int INF = 1000000000;
const double eps = 1e-8;

int main(void) {
  int n;
  cin >> n;
  REP(i, n) {
    int h, w;
    cin >> h >> w;
    vector<string> table(h);
    set<char> s;
    REP(j, h) {
      cin >> table[j];
      REP(k, w) { s.insert(table[j][k]); }
    }
    s.erase('.');
    vector<char> mats;
    FORIT(j, s)
    mats.push_back(*j);
    if (mats.size()) {
      bool flg = true;
      do {
        flg = true;
        vector<string> cp(h);
        REP(k, h) cp[k] = string(table[k]);
        REP(j, mats.size()) {
          int top = h, bottom = 0, left = w, right = 0;
          REP(k, h) REP(l, w) {
            if (cp[k][l] == mats[j]) {
              top = min(top, k);
              bottom = max(bottom, k);
              left = min(left, l);
              right = max(right, l);
            }
          }
          FOR(k, top, bottom + 1) {
            FOR(l, left, right + 1) {
              if (cp[k][l] == '.') {
                flg = false;
                break;
              } else if (cp[k][l] == mats[j]) {
                cp[k][l] = '.';
              }
            }
            if (!flg)
              break;
          }
          if (!flg)
            break;
        }
        if (flg)
          break;
      } while (next_permutation(ALL(mats)));
      if (flg)
        cout << "SAFE" << endl;
      else
        cout << "SUSPICIOUS" << endl;
    } else
      cout << "SAFE" << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <algorithm>
#include <bitset>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>

using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;

int tx[] = {0, 1, 0, -1};
int ty[] = {-1, 0, 1, 0};

static const double EPS = 1e-8;

class Belongings {
public:
  Belongings() : left(100), right(0), upper(100), lower(0) {}
  int left, right, upper, lower;
};

int main() {
  int N;
  while (~scanf("%d", &N)) {
    for (int stage_idx = 0; stage_idx < N; stage_idx++) {
      int H, W;

      scanf("%d %d", &H, &W);
      char stage[2500];
      char hypothesis[2500];
      memset(stage, '.', sizeof(stage));

      map<char, Belongings> layer;

      for (int y = 0; y < H; y++) {
        char line[51];
        scanf("%s", line);
        for (int x = 0; x < W; x++) {
          stage[y * W + x] = line[x];
          // x:0->...
          // y:0
          //   |
          //   v
          //   .
          //   upper
          // left right
          //   lower
          Belongings &it = layer[stage[y * W + x]];
          it.left = min(it.left, x);
          it.right = max(it.right, x);
          it.upper = min(it.upper, y);
          it.lower = max(it.lower, y);
        }
      }

      bool is_safe = false;

      vector<char> order;
      for (map<char, Belongings>::iterator it = layer.begin();
           it != layer.end(); it++) {
        order.push_back(it->first);
      }
      sort(order.begin(), order.end());

      do {
        memset(hypothesis, '.', sizeof(hypothesis));

        for (int i = 0; i < order.size(); i++) {
          char c = order[i];
          Belongings &it = layer[c];
          for (int y = it.upper; y <= it.lower; y++) {
            for (int x = it.left; x <= it.right; x++) {
              hypothesis[y * W + x] = c;
            }
          }
        }

        if (strcmp(hypothesis, stage) == 0) {
          is_safe = true;
          break;
        }
      } while (next_permutation(order.begin(), order.end()));
      printf("%s\\n", is_safe ? "SAFE" : "SUSPICIOUS");
    }
  }
}