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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

const int INF = INT_MAX / 2;

int main() {
  for (;;) {
    int w, h;
    cin >> w >> h;
    if (w == 0)
      return 0;

    int sy, sx, gy, gx;
    vector<vector<int>> py(5), px(5);

    for (int i = 0; i < h; ++i) {
      string s;
      cin >> s;
      for (int j = 0; j < w; ++j) {
        if (s[j] == 'S') {
          sy = i;
          sx = j;
        } else if (s[j] == 'G') {
          gy = i;
          gx = j;
        } else if (s[j] != '.') {
          py[s[j] - '1'].push_back(i);
          px[s[j] - '1'].push_back(j);
        }
      }
    }

    pair<int, int> ret(INF, INF);
    for (int i = 0; i < 5; ++i) {
      int a = (i + 1) % 5;
      int b = (i + 2) % 5;

      int n = py[a].size();
      vector<int> cost(n);
      for (int j = 0; j < n; ++j)
        cost[j] = abs(sy - py[a][j]) + abs(sx - px[a][j]);

      for (int j = 0; j < 3; ++j) {
        int m = py[b].size();
        vector<int> nextCost(m, INF);
        for (int k = 0; k < n; ++k) {
          for (int l = 0; l < m; ++l) {
            nextCost[l] = min(nextCost[l], cost[k] + abs(py[a][k] - py[b][l]) +
                                               abs(px[a][k] - px[b][l]));
          }
        }
        (++a) %= 5;
        (++b) %= 5;
        n = m;
        cost.swap(nextCost);
      }

      for (int j = 0; j < n; ++j)
        ret = min(ret,
                  make_pair(cost[j] + abs(gy - py[a][j]) + abs(gx - px[a][j]),
                            i + 1));
    }

    if (ret.first == INF)
      cout << "NA" << endl;
    else
      cout << ret.second << ' ' << ret.first << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int main() {
  int dy[] = {0, 0, -1, 1};
  int dx[] = {1, -1, 0, 0};

  for (;;) {
    int w, h;
    cin >> w >> h;
    if (w == 0)
      return 0;

    vector<string> grid(h);
    int sy, sx, gy, gx;
    for (int i = 0; i < h; ++i) {
      cin >> grid[i];
      int j = grid[i].find('S');
      if (j != string::npos) {
        sy = i;
        sx = j;
        grid[i][j] = '.';
      }
      j = grid[i].find('G');
      if (j != string::npos) {
        gy = i;
        gx = j;
        grid[i][j] = '.';
      }
    }

    pair<int, int> ret(INT_MAX, INT_MAX);

    for (int k = 0; k < 5; ++k) {
      queue<pair<pair<pair<int, int>, int>, int>> q;
      q.push(make_pair(make_pair(make_pair(sy, sx), 1 << k), 0));
      vector<vector<vector<bool>>> check(
          h, vector<vector<bool>>(w, vector<bool>(32, false)));
      check[sy][sx][1 << k] = true;

      while (!q.empty()) {
        int y0 = q.front().first.first.first;
        int x0 = q.front().first.first.second;
        int pachi0 = q.front().first.second;
        int cost = q.front().second;
        q.pop();

        if (y0 == gy && x0 == gx && pachi0 == 31) {
          ret = min(ret, make_pair(cost, k));
          break;
        }

        for (int i = 0; i < 4; ++i) {
          int y = y0 + dy[i];
          int x = x0 + dx[i];
          if (y < 0 || y >= h || x < 0 || x >= w)
            continue;
          int pachi = pachi0;
          if (grid[y][x] != '.') {
            int j = grid[y][x] - '1';
            if (pachi & (1 << ((j + 4) % 5)))
              pachi |= (1 << j);
          }

          if (!check[y][x][pachi]) {
            check[y][x][pachi] = true;
            q.push(make_pair(make_pair(make_pair(y, x), pachi), cost + 1));
          }
        }
      }
    }

    if (ret.first == INT_MAX)
      cout << "NA" << endl;
    else
      cout << (ret.second + 1) << ' ' << ret.first << endl;
  }
}