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

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <memory.h>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>

using namespace std;

typedef complex<double> xy_t;
typedef pair<xy_t, xy_t> line;
typedef vector<xy_t> polygon;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<int, string> Ps;
typedef vector<int> vec;
typedef vector<vec> mat;
const int INF = 1 << 29;
const double EPS = 1e-10;
const double PI = 3.1415926535897932384626433832795;
const int CLK = CLOCKS_PER_SEC;

#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, m, n) for (int i = m; i < n; i++)
#define repD(i, n) for (int i = n; i >= 0; i--)

const int sz = 1010;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};

int memo[sz][6];
P pos[sz][7];
int cnt[7];

int cost(const P &p1, const P &p2) {
  return abs(p1.first - p2.first) + abs(p1.second - p2.second);
}

void update(int cur, int nxt, int n) {
  rep(i, cnt[cur]) {
    rep(j, cnt[nxt]) {
      memo[j][n + 1] =
          min(memo[j][n + 1], memo[i][n] + cost(pos[i][cur], pos[j][nxt]));
    }
  }
}

int main() {
  int X, Y;
  int num;
  char ch;
  while (cin >> X >> Y && (X || Y)) {
    memset(cnt, 0, sizeof(cnt));
    rep(i, Y) rep(j, X) {
      cin >> ch;
      if (ch == '.')
        continue;
      if (ch == 'S') {
        pos[cnt[0]++][0] = P(j, i);
      } else if (ch == 'G') {
        pos[cnt[6]++][6] = P(j, i);
      } else {
        num = ch - '0';
        pos[cnt[num]++][num] = P(j, i);
      }
    }
    int res = INF;
    int id = -1;

    rep(type, 5) {
      fill(&memo[0][0], &memo[sz - 1][5] + 1, INF);
      memo[0][0] = 0;
      rep(i, 5) {
        int cur = 0, nx = 0;
        if (i == 0) {
          cur = 0;
          nx = 1 + (type + i + 1) % 5;
        } else if (i == 4) {
          cur = 1 + (type + i) % 5;
          nx = 6;
        } else {
          cur = 1 + (type + i) % 5;
          nx = 1 + (type + i + 1) % 5;
        }
        update(cur, nx, i);
      }

      if (memo[0][5] < res) {
        res = memo[0][5];
        id = type;
      }
    }
    if (res == INF)
      cout << "NA" << endl;
    else
      cout << id + 1 << " " << res << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#define _USE_MATH_DEFINES
#include <algorithm>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <math.h>
#include <memory.h>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <time.h>
#include <vector>

using namespace std;

typedef complex<double> xy_t;
typedef pair<xy_t, xy_t> line;
typedef vector<xy_t> polygon;
typedef long long ll;
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<int, string> Ps;
typedef vector<int> vec;
typedef vector<vec> mat;
const int INF = 1 << 29;
const double EPS = 1e-10;
const double PI = 3.1415926535897932384626433832795;
const int CLK = CLOCKS_PER_SEC;

#define rep(i, n) for (int i = 0; i < n; i++)
#define rep2(i, m, n) for (int i = m; i < n; i++)
#define repD(i, n) for (int i = n; i >= 0; i--)

const int sz = 1010;
int dx[] = {1, 0, -1, 0};
int dy[] = {0, -1, 0, 1};

char field[sz][sz];
int memo[sz][sz][5];

int main() {
  int X, Y;
  int sx, sy, gx, gy;
  while (cin >> X >> Y && (X || Y)) {
    rep(i, Y) rep(j, X) {
      cin >> field[j][i];
      if (field[j][i] == 'S') {
        field[j][i] = '.';
        sx = j, sy = i;
      } else if (field[j][i] == 'G') {
        field[j][i] = '.';
        gx = j, gy = i;
      }
    }
    int res = INF;
    int id = -1;

    rep(type, 5) {
      memset(memo, -1, sizeof(memo));
      queue<PP> que;
      que.push(PP(0, P(sx, sy)));
      memo[sx][sy][0] = 0;
      while (!que.empty()) {
        PP pp = que.front();
        que.pop();
        int stage = pp.first;
        char next = (char)('1' + (stage + type + 1) % 5);
        int x = pp.second.first;
        int y = pp.second.second;
        if (x == gx && y == gy && stage == 4) {
          if (memo[gx][gy][stage] < res) {
            res = memo[gx][gy][stage];
            id = type;
          }
        }
        rep(i, 4) {
          int x2 = x + dx[i];
          int y2 = y + dy[i];
          if (0 <= x2 && x2 < X && 0 <= y2 && y2 < Y) {
            if (memo[x2][y2][stage] < 0) {
              memo[x2][y2][stage] = memo[x][y][stage] + 1;
              que.push(PP(stage, P(x2, y2)));
            }
            if (stage < 4 && field[x2][y2] == next &&
                memo[x2][y2][stage + 1] < 0) {
              memo[x2][y2][stage + 1] = memo[x][y][stage] + 1;
              que.push(PP(stage + 1, P(x2, y2)));
            }
          }
        }
      }
    }

    if (res == INF)
      cout << "NA" << endl;
    else
      cout << id + 1 << " " << res << endl;
  }
  return 0;
}