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

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

bool ans;

// 文字cの出現するx,y座標の最大値と最小値の保持に使う
struct range {
  int min_x, min_y, max_x, max_y;
  range(int min_x_, int min_y_, int max_x_, int max_y_) {
    min_x = min_x_;
    min_y = min_y_;
    max_x = max_x_;
    max_y = max_y_;
  }
};

void debug(const vector<string> &m) {
  cout << "[debug]" << endl;
  for (int y = 0; y < m.size(); y++) {
    cout << m[y] << endl;
  }
  cout << endl;
}

void debug2(const vector<char> &vc, const vector<range> &vr) {
  for (int i = 0; i < vc.size(); i++) {
    range r = vr[i];
    cout << vc[i] << " " << endl;
    cout << "x => [" << r.min_x << "," << r.max_x << "] ";
    cout << "y => [" << r.min_y << "," << r.max_y << "] ";
    cout << endl << endl;
  }
}

// 文字 c の出現する x,y 座標の最大値と最小値を求める
range search_range(const vector<string> &m, char c) {
  int min_x = -1, min_y = -1, max_x = -1, max_y = -1;
  for (int y = 0; y < m.size(); y++) {
    for (int x = 0; x < m[y].size(); x++) {
      if (m[y][x] == c) {
        min_x = (min_x == -1) ? x : min(min_x, x);
        min_y = (min_y == -1) ? y : min(min_y, y);
        max_x = (max_x == -1) ? x : max(max_x, x);
        max_y = (max_y == -1) ? y : max(max_y, y);
      }
    }
  }
  range r(min_x, min_y, max_x, max_y);
  return r;
}

// 文字 c について長方形かどうか
bool check(const vector<string> &m, range r, char c) {
  int cnt = 0;
  for (int y = r.min_y; y <= r.max_y; y++) {
    for (int x = r.min_x; x <= r.max_x; x++) {
      if (m[y][x] == c || m[y][x] == '*') {
        cnt++;
      }
    }
  }

  // cout << "search " << c << " cnt : " << cnt << endl;
  // cout << "(" << r.min_x << "," << r.min_y << ") => (" << r.max_x << "," <<
  // r.max_y << ")" << endl;

  if (cnt != (r.max_x - r.min_x + 1) * (r.max_y - r.min_y + 1)) {
    return false;
  }

  for (int y = 0; y < m.size(); y++) {
    for (int x = 0; x < m[y].size(); x++) {
      if (r.min_x <= x && r.min_y <= y && x <= r.max_x && y <= r.max_y) {
      } else if (m[y][x] == c) {
        return false;
      }
    }
  }
  return true;
}

// 文字 c を' *' に置き換える (荷物を取り除く)
void remove(vector<string> &m, range r, char c) {
  for (int y = r.min_y; y <= r.max_y; y++) {
    for (int x = r.min_x; x <= r.max_x; x++) {
      if (m[y][x] == c) {
        m[y][x] = '*';
      }
    }
  }
}

void dfs(int id, vector<bool> memo, vector<string> m, vector<char> vc,
         vector<range> vr) {
  memo[id] = true;

  // 長方形かどうか
  bool is_rect = check(m, vr[id], vc[id]);
  if (is_rect == false) {
    return;
  }

  // 文字 vc[id] を '*' に置き換える (荷物を取り除く)
  remove(m, vr[id], vc[id]);

  // cout << vc[id] << " is rectangle! " << endl;
  // debug( m );

  // すべて調べたかどうか
  int cnt = 0;
  for (int i = 0; i < memo.size(); i++) {
    if (memo[i])
      cnt++;
  }
  if (cnt == memo.size() && is_rect) {
    ans = true;
    return;
  }

  for (int i = 0; i < memo.size(); i++) {
    if (memo[i] == false) {
      // cout << "next : " << vc[i] << endl;
      dfs(i, memo, m, vc, vr);
    }
  }
}

void solve(const vector<string> &m) {
  char ch[256] = {0};
  vector<char> vc;
  vector<range> vr;
  ans = false;

  // 出現する文字を調べる
  for (int y = 0; y < m.size(); y++) {
    for (int x = 0; x < m[y].size(); x++) {
      if (m[y][x] >= 'A' && m[y][x] <= 'Z') {
        ch[m[y][x]] = 1;
      }
    }
  }
  for (char c = 'A'; c <= 'Z'; c++) {
    if (ch[c])
      vc.push_back(c);
  }

  // 文字がなかったら "SAFE"
  if (vc.size() == 0) {
    ans = true;
  }

  // 各文字 c について x,y 座標の最大値と最小値を求める
  for (int i = 0; i < vc.size(); i++) {
    range r = search_range(m, vc[i]);
    vr.push_back(r);
  }
  // debug2( vc , vr );

  // DFSで重なる順番をすべて調べる
  vector<bool> memo(vc.size());
  for (int k = 0; k < vc.size(); k++) {
    for (int i = 0; i < memo.size(); i++) {
      memo[i] = false;
    }
    dfs(k, memo, m, vc, vr);
  }
}

int main() {
  int T;
  cin >> T;
  for (int t_ = 0; t_ < T; t_++) {
    int w, h;
    cin >> h >> w;

    vector<string> m(h);
    for (int y = 0; y < h; y++) {
      cin >> m[y];
    }

    solve(m);

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

Error: WA

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

bool ans;

// 文字cの出現するx,y座標の最大値と最小値の保持に使う
struct range {
  int min_x, min_y, max_x, max_y;
  range(int min_x_, int min_y_, int max_x_, int max_y_) {
    min_x = min_x_;
    min_y = min_y_;
    max_x = max_x_;
    max_y = max_y_;
  }
};

void debug(const vector<string> &m) {
  cout << "[debug]" << endl;
  for (int y = 0; y < m.size(); y++) {
    cout << m[y] << endl;
  }
  cout << endl;
}

void debug2(const vector<char> &vc, const vector<range> &vr) {
  for (int i = 0; i < vc.size(); i++) {
    range r = vr[i];
    cout << vc[i] << " " << endl;
    cout << "x => [" << r.min_x << "," << r.max_x << "] ";
    cout << "y => [" << r.min_y << "," << r.max_y << "] ";
    cout << endl << endl;
  }
}

// 文字 c の出現する x,y 座標の最大値と最小値を求める
range search_range(const vector<string> &m, char c) {
  int min_x = -1, min_y = -1, max_x = -1, max_y = -1;
  for (int y = 0; y < m.size(); y++) {
    for (int x = 0; x < m[y].size(); x++) {
      if (m[y][x] == c) {
        min_x = (min_x == -1) ? x : min(min_x, x);
        min_y = (min_y == -1) ? y : min(min_y, y);
        max_x = (max_x == -1) ? x : max(max_x, x);
        max_y = (max_y == -1) ? y : max(max_y, y);
      }
    }
  }
  range r(min_x, min_y, max_x, max_y);
  return r;
}

// 文字 c について長方形かどうか
bool check(const vector<string> &m, range r, char c) {
  int cnt = 0;
  for (int y = r.min_y; y <= r.max_y; y++) {
    for (int x = r.min_x; x <= r.max_x; x++) {
      if (m[y][x] == c || m[y][x] == '*') {
        cnt++;
      }
    }
  }

  // cout << "search " << c << " cnt : " << cnt << endl;
  // cout << "(" << r.min_x << "," << r.min_y << ") => (" << r.max_x << "," <<
  // r.max_y << ")" << endl;

  if (cnt != (r.max_x - r.min_x + 1) * (r.max_y - r.min_y + 1)) {
    return false;
  }

  for (int y = 0; y < m.size(); y++) {
    for (int x = 0; x < m[y].size(); x++) {
      if (r.min_x <= x && r.min_y <= y && x <= r.max_x && y <= r.max_y) {
      } else if (m[y][x] == c) {
        return false;
      }
    }
  }
  return true;
}

// 文字 c を' *' に置き換える (荷物を取り除く)
void remove(vector<string> &m, range r, char c) {
  for (int y = r.min_y; y <= r.max_y; y++) {
    for (int x = r.min_x; x <= r.max_y; x++) {
      if (m[y][x] == c) {
        m[y][x] = '*';
      }
    }
  }
}

void dfs(int id, vector<bool> memo, vector<string> m, vector<char> vc,
         vector<range> vr) {
  memo[id] = true;

  // 長方形かどうか
  bool is_rect = check(m, vr[id], vc[id]);
  if (is_rect == false) {
    return;
  }

  // 文字 vc[id] を '*' に置き換える (荷物を取り除く)
  remove(m, vr[id], vc[id]);

  // cout << vc[id] << " is rectangle! " << endl;
  // debug( m );

  // すべて調べたかどうか
  int cnt = 0;
  for (int i = 0; i < memo.size(); i++) {
    if (memo[i])
      cnt++;
  }
  if (cnt == memo.size() && is_rect) {
    ans = true;
    return;
  }

  for (int i = 0; i < memo.size(); i++) {
    if (memo[i] == false) {
      // cout << "next : " << vc[i] << endl;
      // dfs( i , memo , m , vc , vr );
    }
  }
}

void solve(const vector<string> &m) {
  char ch[256] = {0};
  vector<char> vc;
  vector<range> vr;
  ans = false;

  // 出現する文字を調べる
  for (int y = 0; y < m.size(); y++) {
    for (int x = 0; x < m[y].size(); x++) {
      if (m[y][x] >= 'A' && m[y][x] <= 'Z') {
        ch[m[y][x]] = 1;
      }
    }
  }
  for (char c = 'A'; c <= 'Z'; c++) {
    if (ch[c])
      vc.push_back(c);
  }

  // 文字がなかったら "SAFE"
  if (vc.size() == 0) {
    ans = true;
  }

  // 各文字 c について x,y 座標の最大値と最小値を求める
  for (int i = 0; i < vc.size(); i++) {
    range r = search_range(m, vc[i]);
    vr.push_back(r);
  }
  // debug2( vc , vr );

  // DFSで重なる順番をすべて調べる
  vector<bool> memo(vc.size());
  for (int k = 0; k < vc.size(); k++) {
    for (int i = 0; i < memo.size(); i++) {
      memo[i] = false;
    }
    dfs(k, memo, m, vc, vr);
  }
}

int main() {
  int T;
  cin >> T;
  for (int t_ = 0; t_ < T; t_++) {
    int w, h;
    cin >> h >> w;

    vector<string> m(h);
    for (int y = 0; y < h; y++) {
      cin >> m[y];
    }

    solve(m);

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