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

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#define F first
#define MAX 1000
#define S second
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
using namespace std;
typedef pair<int, int> P;
struct Pox {
  int x, y, dir;
  Pox(int x = -1, int y = -1, int dir = -1) : x(x), y(y), dir(dir) {}
};
int dx[] = {+0, +1, +0, -1}; // N,E,S,W
int dy[] = {-1, +0, +1, +0};
char G[MAX][MAX];
int visited[MAX][MAX][4];
P src;

int getDir(char c) {
  switch (c) {
  case 'N':
    return 0;
  case 'E':
    return 1;
  case 'S':
    return 2;
  case 'W':
    return 3;
  }
}

char toChar(int c) {
  switch (c) {
  case 0:
    return 'N';
  case 1:
    return 'E';
  case 2:
    return 'S';
  case 3:
    return 'W';
  }
}

void move(int H, int W, int x, int y, int &dir) {
  // cout << x << "," << y << " " << dir;
  while (true) {
    x = x - dx[dir];
    y = y - dy[dir];
    // cout << " x = " << x << ", y = " << y << " G = " << G[y][x] << " ";
    if (!(0 <= x && x < W && 0 <= y && y < H)) {
      // cout << " X1X";
      y = y + dy[dir];
      x = x + dx[dir];
      dir = (dir - 1 + 4) % 4;
    } else if (G[y][x] == '#') {
      // cout << " X2X " << "G["<<src.S<<"]["<<src.F<<"]" << " ";
      y = y + dy[dir];
      x = x + dx[dir];
      dir = (dir - 1 + 4) % 4;
    } else {
      // cout << " X3X";
      break;
    }
  }
  // cout << " -> " << x << "," << y << " " << dir << endl;
}

void move2(int H, int W, int x, int y, int &dir) {
  // cout << x << "," << y << " " << dir;
  while (true) {
    x = x + dx[dir];
    y = y + dy[dir];
    // cout << " x = " << x << ", y = " << y << " G = " << G[y][x] << " ";
    if (!(0 <= x && x < W && 0 <= y && y < H)) {
      // cout << " X1X";
      y = y - dy[dir];
      x = x - dx[dir];
      dir = (dir + 1) % 4;
    } else if (G[y][x] == '#') {
      // cout << " X2X " << "G["<<src.S<<"]["<<src.F<<"]" << " ";
      y = y - dy[dir];
      x = x - dx[dir];
      dir = (dir + 1) % 4;
    } else {
      // cout << " X3X";
      break;
    }
  }
  // cout << " -> " << x << "," << y << " " << dir << endl;
}

int main() {
  int H, W;
  long long L;
  while (cin >> H >> W >> L, H | W | L) {
    assert(H <= 100);
    assert(W <= 100);
    assert(L <= 1000000000000000000LL);

    /*
    if(W == 1 && H == 1)
      {
        cout << H << " " << W << " " << L << endl;
        char c;
        cin >> c;
        cout << c << endl;
        assert(false);
      }
    */
    int dir;
    rep(i, H) {
      string line;
      cin >> line;
      rep(j, line.size()) {
        assert(j < W);
        G[i][j] = line[j];
        if (!(G[i][j] == '.' || G[i][j] == '#'))
          src = P(j, i), dir = getDir(G[i][j]), G[i][j] = '.';

        rep(k, 4) visited[i][j][k] = -1;
      }
    }

    long long phase = 0;
    vector<Pox> path;
    path.push_back(Pox(src.F, src.S, dir));
    P prep = src;
    int preD = dir;

    while (true) {
      // cout << phase << "-th : " << src.F << "," << src.S << endl;
      if (prep != src)
        preD = dir;
      if (phase >= L) {
        move(H, W, src.F, src.S, dir);
        cout << src.S + 1 << " " << src.F + 1 << " " << toChar(dir) << endl;
        break;
      }
      if (visited[src.S][src.F][dir] != -1) {
        /*
        L -= phase;
        L %= (phase-visited[src.S][src.F][dir]);
        for(int i=0;i<path.size();i++)
          {
            if(path[i].x == src.F && path[i].y == src.S)
              {
                move(H,W,path[i+L].x,path[i+L].y,path[i+L].dir);
                cout << path[i+L].y+1 << " " << path[i+L].x+1 << " " <<
        toChar(path[i+L].dir) << endl; break;
              }
          }
        */

        L -= phase;
        L %= (phase - visited[src.S][src.F][dir]);
        L += (phase - visited[src.S][src.F][dir]);
        // cout << "L = " << L << " dir = " << dir << endl;
        for (int i = 0; i < L; i++) {
          if (prep != src)
            preD = dir;
          src.F += dx[dir];
          src.S += dy[dir];

          if (!(0 <= src.F && src.F < W && 0 <= src.S && src.S < H)) {
            src.F -= dx[dir];
            src.S -= dy[dir];
            dir = (dir + 1) % 4;
            i--;
            continue;
          } else if (G[src.S][src.F] == '#') {
            src.F -= dx[dir];
            src.S -= dy[dir];
            dir = (dir + 1) % 4;
            i--;
            continue;
          }
        }
        // move(H,W,src.F,src.S,dir);
        // move2(H,W,src.F,src.S,dir);

        cout << src.S + 1 << " " << src.F + 1 << " " << toChar(dir) << endl;
        break;
      }

      visited[src.S][src.F][dir] = phase;
      src.F += dx[dir];
      src.S += dy[dir];
      if (!(0 <= src.F && src.F < W && 0 <= src.S && src.S < H)) {
        src.F -= dx[dir];
        src.S -= dy[dir];
        dir = (dir + 1) % 4;
        continue;
      } else if (G[src.S][src.F] == '#') {
        src.F -= dx[dir];
        src.S -= dy[dir];
        dir = (dir + 1) % 4;
        continue;
      }

      path.push_back(Pox(src.F, src.S, dir));
      phase++;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <iostream>
#include <vector>
#define F first
#define S second
#define REP(i, s, n) for (int i = s; i < n; i++)
#define rep(i, n) REP(i, 0, n)
using namespace std;
typedef pair<int, int> P;
struct Pox {
  int x, y, dir;
  Pox(int x = -1, int y = -1, int dir = -1) : x(x), y(y), dir(dir) {}
};
int dx[] = {+0, +1, +0, -1}; // N,E,S,W
int dy[] = {-1, +0, +1, +0};
char G[100][100];
int visited[100][100][4];
P src;

int getDir(char c) {
  switch (c) {
  case 'N':
    return 0;
  case 'E':
    return 1;
  case 'S':
    return 2;
  case 'W':
    return 3;
  }
}

char toChar(int c) {
  switch (c) {
  case 0:
    return 'N';
  case 1:
    return 'E';
  case 2:
    return 'S';
  case 3:
    return 'W';
  }
}

void move(int H, int W, int &dir) {
  cout << "dir = " << dir << endl;
  while (true) {
    src.S = src.S + dx[dir];
    src.F = src.F + dy[dir];
    if (!(0 <= src.F && src.F < W && 0 <= src.S && src.S < H)) {
      src.S = src.S - dx[dir];
      src.F = src.F - dy[dir];
      dir = (dir + 1) % 4;
    } else if (G[src.S][src.F] == '#') {
      src.S = src.S - dx[dir];
      src.F = src.F - dy[dir];
      dir = (dir + 1) % 4;
    } else {
      src.S = src.S - dx[dir];
      src.F = src.F - dy[dir];
      break;
    }
  }
  cout << "aft = " << dir << endl;
}

int main() {
  int H, W, L;
  while (cin >> H >> W >> L, H | W | L) {
    if (W == 1 && H == 1) {
      cout << H << " " << W << " " << L << endl;
      char c;
      cin >> c;
      cout << c << endl;
      assert(false);
    }
    int dir;
    rep(i, H) {
      string line;
      cin >> line;
      rep(j, W) {
        G[i][j] = line[j];
        if (!(G[i][j] == '.' || G[i][j] == '#'))
          src = P(j, i), dir = getDir(G[i][j]), G[i][j] = '.';

        rep(k, 4) visited[i][j][k] = -1;
      }
    }

    int phase = 0;
    vector<Pox> path;
    path.push_back(Pox(src.F, src.S, dir));

    while (true) {
      if (phase >= L) {
        cout << src.S + 1 << " " << src.F + 1 << " " << toChar(dir) << endl;
        break;
      }
      if (visited[src.S][src.F][dir] != -1) {
        L -= phase;
        L %= (phase - visited[src.S][src.F][dir]);
        for (int i = 0; i < path.size(); i++) {
          if (path[i].x == src.F && path[i].y == src.S) {
            cout << path[i + L].y + 1 << " " << path[i + L].x + 1 << " "
                 << toChar(path[i + L].dir) << endl;
            break;
          }
        }
        break;
      }

      visited[src.S][src.F][dir] = phase;
      src.F += dx[dir];
      src.S += dy[dir];
      if (!(0 <= src.F && src.F < W && 0 <= src.S && src.S < H)) {
        src.F -= dx[dir];
        src.S -= dy[dir];
        dir = (dir + 1) % 4;
        continue;
      } else if (G[src.S][src.F] == '#') {
        src.F -= dx[dir];
        src.S -= dy[dir];
        dir = (dir + 1) % 4;
        continue;
      }

      path.push_back(Pox(src.F, src.S, dir));
      phase++;
    }
  }
  return 0;
}