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

#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define ll long long
#define vvi vector<vector<int>>
#define vi vector<int>
#define All(X) X.begin(), X.end()
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define pb push_back
#define pii pair<int, int>
#define mp make_pair
#define pi 3.14159265359
#define shosu(X) fixed << setprecision(X)
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

int H, W;
ll int L;
char grid[150][150];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1}; // N,E,S,W
ll int memo[150][150][4];
int dir, px, py;

int rotate(int a) { return (a + 1) % 4; }
bool inrange(int x, int y) { return (x > -1 && y > -1 && x < H && y < W); }
int main() {
  while (1) {
    cin >> H >> W >> L;
    if (H == 0 && W == 0 && L == 0)
      break;
    REP(i, H) {
      string str;
      cin >> str;
      REP(j, str.size()) {
        grid[i][j] = str[j];
        if (grid[i][j] == 'N') {
          dir = 0;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'E') {
          dir = 1;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'S') {
          dir = 2;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'W') {
          dir = 3;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
      }
    }
    ll int step = 0;
    REP(i, 150) REP(j, 150) REP(k, 4) memo[i][j][k] = -1;
    memo[px][py][dir] = 0;
    while (1) {
      if (step == L)
        goto End;
      int nx = px + dx[dir];
      int ny = py + dy[dir];
      if (grid[nx][ny] == '.' && inrange(nx, ny)) {
        step++;
        px = nx;
        py = ny;
        if (memo[px][py][dir] != -1) {
          // cout << px << " " << py << " " << dir << " "<< memo[px][py][dir] <<
          // " " << step << endl;
          // a,b,c
          ll int a = step - memo[px][py][dir];
          ll int b = L - step;
          step += a * (b / a);
          if (step == L)
            goto End;
        } else {
          memo[px][py][dir] = step;
        }
      }
      if (!inrange(nx, ny) || grid[nx][ny] == '#') {
        dir = rotate(dir);
      }
    }
  End:
    string ans = "NESW";
    cout << px + 1 << " " << py + 1 << " " << ans[dir] << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define ll long long
#define vvi vector<vector<int>>
#define vi vector<int>
#define All(X) X.begin(), X.end()
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define pb push_back
#define pii pair<int, int>
#define mp make_pair
#define pi 3.14159265359
#define shosu(X) fixed << setprecision(X)
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

int H, W, L;
char grid[150][150];
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1}; // N,E,S,W
ll int memo[150][150][4];
int dir, px, py;

int rotate(int a) { return (a + 1) % 4; }
bool inrange(int x, int y) { return (x > -1 && y > -1 && x < H && y < W); }
int main() {
  while (1) {
    REP(i, 150) REP(j, 150) REP(k, 4) memo[i][j][k] = -1;
    cin >> H >> W >> L;
    if (H == 0 && W == 0 && L == 0)
      break;
    REP(i, H) {
      REP(j, W) {
        cin >> grid[i][j];
        if (grid[i][j] == 'N') {
          dir = 0;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'E') {
          dir = 1;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'S') {
          dir = 2;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
        if (grid[i][j] == 'W') {
          dir = 3;
          px = i;
          py = j;
          grid[i][j] = '.';
        }
      }
    }
    ll int step = 0;
    memo[px][py][dir] = 0;
    while (1) {
      if (step == L)
        break;
      int nx = px + dx[dir];
      int ny = py + dy[dir];
      if (grid[nx][ny] == '.') {
        px = nx;
        py = ny;
        if (memo[px][py][dir] != -1) {
          // a,b,c
          ll int a = step - memo[px][py][dir];
          ll int b = L - step;
          step += a * (b / a);
          if (step == L)
            break;
        } else {
          memo[px][py][dir] = step;
        }
        step++;
      }
      if (!inrange(nx, ny) || grid[nx][ny] == '#') {
        dir = rotate(dir);
      }
    }
    string ans = "NESW";
    cout << px + 1 << " " << py + 1 << " " << ans[dir] << endl;
  }
}