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

//
// Created by 拓真 on 2018/06/30.
//

#include "bits/stdc++.h"
using namespace std;
#define FOR(i, a, b) for (int i = a; i < b; i++)
#define rep(i, b) FOR(i, 0, b)
#define INF mugen
#define dump(x) cerr << #x << "=" << x << endl
#define all(a) (a).begin(), (a).end()
typedef vector<int> V;
typedef vector<V> VV;
typedef vector<VV> VVV;
template <class T> void chmin(T &a, T const &b) {
  if (b < a)
    a = b;
}

typedef pair<int, int> P;
typedef long long ll;
#define int long long
struct robot {
  robot(){};
  int x, y;
  int dir;
  robot(int x, int y, int dir) {
    this->x = x;
    this->y = y;
    this->dir = dir;
  }
};

char toc(int x) {
  if (x == 0)
    return 'N';
  else if (x == 1)
    return 'E';
  else if (x == 2)
    return 'S';
  else
    return 'W';
}
int dp[110][110][5];
vector<string> maze;
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
int h, w;

bool inrange(int x, int y) { return x >= 0 && x < w && y >= 0 && y < h; }

signed main() {
  ll L;
  while (cin >> h >> w >> L, h) {

    rep(i, 110) rep(j, 110) rep(k, 5) dp[i][j][k] = -1;
    maze.clear();
    rep(i, h) {
      string s;
      cin >> s;
      maze.push_back(s);
    }

    robot pre;
    rep(i, h) rep(j, w) {
      if (maze[i][j] == 'N') {
        pre = robot(j, i, 0);
      }
      if (maze[i][j] == 'E') {
        pre = robot(j, i, 1);
      }
      if (maze[i][j] == 'S') {
        pre = robot(j, i, 2);
      }
      if (maze[i][j] == 'W') {
        pre = robot(j, i, 3);
      }
    }

    bool flag = false;
    dp[pre.y][pre.x][pre.dir] = 0;
    ll turn = 1;
    bool rooped = false;
    while (turn <= L) {
      int nx, ny, ndir;
      rep(i, 4) {
        ndir = (pre.dir + i) % 4;
        nx = pre.x + dx[ndir];
        ny = pre.y + dy[ndir];
        if (inrange(nx, ny) && maze[ny][nx] != '#') {
          pre.x = nx;
          pre.y = ny;
          pre.dir = ndir;
          break;
        }
      }
      if (!rooped && dp[pre.y][pre.x][pre.dir] >= 0) {
        rooped = true;
        ll roop = turn - dp[pre.y][pre.x][pre.dir];
        turn += (L - turn) / roop * roop;
        turn++;
      } else {
        dp[pre.y][pre.x][pre.dir] = turn;
        turn++;
      }
    }

    cout << pre.y + 1 << ' ' << pre.x + 1 << ' ' << toc(pre.dir) << endl;
  }
}


Error: TLE

Fixed submission:

//
// Created by 拓真 on 2018/06/30.
//

#include "bits/stdc++.h"
using namespace std;
#define FOR(i, a, b) for (int i = a; i < b; i++)
#define rep(i, b) FOR(i, 0, b)
#define INF mugen
#define dump(x) cerr << #x << "=" << x << endl
#define all(a) (a).begin(), (a).end()
typedef vector<int> V;
typedef vector<V> VV;
typedef vector<VV> VVV;
template <class T> void chmin(T &a, T const &b) {
  if (b < a)
    a = b;
}

typedef pair<int, int> P;
typedef long long ll;
#define int long long
struct robot {
  robot(){};
  int x, y;
  int dir;
  robot(int x, int y, int dir) {
    this->x = x;
    this->y = y;
    this->dir = dir;
  }
};

char toc(int x) {
  if (x == 0)
    return 'N';
  else if (x == 1)
    return 'E';
  else if (x == 2)
    return 'S';
  else
    return 'W';
}
int dp[110][110][5];
vector<string> maze;
int dx[] = {0, 1, 0, -1};
int dy[] = {-1, 0, 1, 0};
signed main() {
  int h, w;
  ll L;
  while (cin >> h >> w >> L, h) {

    rep(i, 110) rep(j, 110) rep(k, 5) dp[i][j][k] = 0;
    maze.clear();
    rep(i, h) {
      string s;
      cin >> s;
      maze.push_back(s);
    }

    robot pre;
    rep(i, h) rep(j, w) {
      if (maze[i][j] == 'N') {
        pre = robot(j, i, 0);
      }
      if (maze[i][j] == 'E') {
        pre = robot(j, i, 1);
      }
      if (maze[i][j] == 'S') {
        pre = robot(j, i, 2);
      }
      if (maze[i][j] == 'W') {
        pre = robot(j, i, 3);
      }
    }

    bool flag = false;

    dp[pre.y][pre.x][pre.dir] = 1;
    for (int i = 0; i < L; i++) {

      int nexty = pre.y + dy[pre.dir];
      int nextx = pre.x + dx[pre.dir];
      if (nexty >= 0 && nexty < h && nextx >= 0 && nextx < w &&
          maze[nexty][nextx] != '#') {
        pre = robot(nextx, nexty, pre.dir);

      } else {
        int id = 1;
        while (1) {
          int nx = pre.x + dx[(pre.dir + id) % 4];
          int ny = pre.y + dy[(pre.dir + id) % 4];
          if (nx >= 0 && nx < w && ny >= 0 && ny < h && maze[ny][nx] == '.') {
            pre = robot(pre.x + dx[(pre.dir + id) % 4],
                        pre.y + dy[(pre.dir + id) % 4], (pre.dir + id) % 4);
            break;
          }
          id++;
        }
      }

      // cout<<pre.y+1<<' '<<pre.x+1<<' '<<toc(pre.dir)<<endl;

      if (!flag && dp[pre.y][pre.x][pre.dir]) {
        int x = i + 1 - dp[pre.y][pre.x][pre.dir];
        // cerr<<"cut";
        i += ((L - i) / x) * x;
        // cerr<<(L/x)*x;
        // flag=true;
      }
      dp[pre.y][pre.x][pre.dir] = i + 1;
    }

    cout << pre.y + 1 << ' ' << pre.x + 1 << ' ' << toc(pre.dir) << endl;
  }
}