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

#include <algorithm>
#include <cstdio>
#include <vector>
#pragma warning(disable : 4996)
using namespace std;
int H, W;
char c[1009][1009];
int main() {
  while (scanf("%d%d", &W, &H), W) {
    for (int i = 0; i < H; i++)
      scanf("%s", &c[i]);
    vector<vector<pair<int, int>>> v(7);
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (c[i][j] == '.')
          continue;
        if (c[i][j] == 'S')
          v[0].push_back(make_pair(i, j));
        else if (c[i][j] == 'G')
          v[6].push_back(make_pair(i, j));
        else
          v[c[i][j] - 48].push_back(make_pair(i, j));
      }
    }
    int ret = 999999999, p = -1;
    for (int i = 0; i < 5; i++) {
      vector<int> r = {0};
      for (int j = 1; j < 5; j++)
        r.push_back((i + j) % 5 + 1);
      r.push_back(6);
      vector<vector<int>> dp(6);
      dp[0] = {0};
      for (int j = 1; j < 6; j++) {
        dp[j].resize(v[r[j]].size());
        for (int k = 0; k < dp[j].size(); k++) {
          dp[j][k] = 999999999;
          for (int l = 0; l < dp[j - 1].size(); l++) {
            int dist = abs(v[r[j]][k].first - v[r[j - 1]][l].first) +
                       abs(v[r[j]][k].second - v[r[j - 1]][l].second);
            dp[j][k] = min(dp[j][k], dp[j - 1][l] + dist);
          }
        }
      }
      if (ret > dp[5][0]) {
        ret = dp[5][0];
        p = i + 1;
      }
    }
    if (ret == 999999999)
      puts("NA");
    else
      printf("%d %d\\n", p, ret);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <tuple>
using namespace std;
queue<tuple<int, int, int, int>> Q;
bool x[1020][1020][32];
int H, W, p[1020][1020], sx, sy, gx, gy;
int main() {
  while (true) {
    for (int i = 0; i < 1020; i++) {
      for (int j = 0; j < 1020; j++) {
        p[i][j] = -1;
        for (int k = 0; k < 32; k++)
          x[i][j][k] = false;
      }
    }
    cin >> H >> W;
    int minx = 1 << 30, minid = 0;
    if (H == 0 && W == 0)
      break;
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        char v;
        cin >> v;
        if (v == 'S') {
          sx = i;
          sy = j;
          p[i][j] = 10;
        } else if (v == 'G') {
          gx = i;
          gy = j;
          p[i][j] = 10;
        } else if (v == '.') {
          p[i][j] = 10;
        } else {
          p[i][j] = (int)(v - '1');
        }
      }
    }
    for (int t = 0; t < 5; t++) {
      for (int i = 0; i < 1020; i++) {
        for (int j = 0; j < 1020; j++) {
          for (int k = 0; k < 32; k++)
            x[i][j][k] = false;
        }
      }
      int res = 1 << 30;
      Q.push(make_tuple(sx, sy, 1 << t, 0));
      x[sx][sy][1 << t] = true;
      while (!Q.empty()) {
        int a1 = get<0>(Q.front()), a2 = get<1>(Q.front());
        int a3 = get<2>(Q.front()), a4 = get<3>(Q.front());
        Q.pop();
        if (a1 == gx && a2 == gy && a3 == 31) {
          if (res > a4)
            res = a4;
        }
        int bit[5];
        for (int j = 0; j < 5; j++)
          bit[j] = (a3 / (1 << j)) % 2;
        int dx[4] = {0, -1, 0, 1}, dy[4] = {1, 0, -1, 0};
        for (int i = 0; i < 4; i++) {
          int cx = a1 + dx[i], cy = a2 + dy[i];
          if (p[cx][cy] == -1)
            continue;
          if (p[cx][cy] == 10) {
            if (x[cx][cy][a3] == false) {
              Q.push(make_tuple(cx, cy, a3, a4 + 1));
              x[cx][cy][a3] = true;
            }
          } else {
            int I = a3;
            if (bit[(p[cx][cy] + 4) % 5] == 1 && bit[p[cx][cy]] == 0)
              a3 += (1 << p[cx][cy]);
            if (x[cx][cy][a3] == false) {
              Q.push(make_tuple(cx, cy, a3, a4 + 1));
              x[cx][cy][a3] = true;
            }
            if (x[cx][cy][I] == false) {
              Q.push(make_tuple(cx, cy, I, a4 + 1));
              x[cx][cy][I] = true;
            }
          }
        }
      }
      if (minx > res) {
        minx = res;
        minid = t;
      }
    }
    if (minx < 1000000000) {
      cout << minid + 1 << ' ' << minx << endl;
    } else {
      cout << "NA" << endl;
    }
  }
  return 0;
}