Problem p01437 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define ALL(c) c.begin(), c.end()
#define RALL(c) c.rbegin(), c.rend()
#define SORT(x) sort((x).begin(), (x).end())
#define REP(i, x, y) for (int i = (x); i < (y); ++i)
#define MP(a, b) make_pair((a), (b))
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int, int> pii;
// template<typename T> using vec=std::vector<T>;

const int INF = 1 << 30;
const long long int INF_ = 1LL << 58;
const double EPS = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

struct State {
  int y, x, dir;
};

void Solve() {
  while (true) {
    ll h, w, l;
    cin >> h >> w >> l;
    if (h == 0 && w == 0 && l == 0)
      break;
    vector<string> cells(h);
    REP(i, 0, h) cin >> cells[i];

    const char empty = '.', wall = '#';
    const int north = 0, east = 1, south = 2, west = 3;
    int y, x, dir;
    REP(i, 0, h) REP(j, 0, w) if (cells[i][j] != empty && cells[i][j] != wall) {
      y = i;
      x = j;
      switch (cells[i][j]) {
      case 'N':
        dir = north;
        break;
      case 'E':
        dir = east;
        break;
      case 'S':
        dir = south;
        break;
      case 'W':
        dir = west;
        break;
      default:
        break;
      }
      cells[i][j] = empty;
      break;
    }

    int rotate[4];
    REP(i, 0, 4) rotate[i] = (i + 1) % 4;

    // State memo[100][100][4];
    // REP(i,0,h) REP(j,0,w) REP(k,0,4){
    // int y_=i,x_=j;
    // int ny=y_+dy[k],nx=x_+dx[k];
    // while(0<=ny&&ny<h&&0<=nx&&nx<w&&cells[ny][nx]==empty){
    // y_=ny; x_=nx;
    // ny=y_+dy[k]; nx=x_+dx[k];
    //}
    // memo[i][j][k]={y_,x_,rotate[k]};
    //}

    const int dx[] = {0, 1, 0, -1}, dy[] = {-1, 0, 1, 0};
    ll visited[100][100][4];
    fill_n((ll *)visited, 100 * 100 * 4, -1);
    ll cnt = 0;
    while (cnt < l) {
      dump(y);
      dump(x);
      if (visited[y][x][dir] == -1)
        visited[y][x][dir] = cnt;
      else {
        ll tmp = 0;
        while (cnt + tmp + cnt - visited[y][x][dir] <= l)
          tmp += (cnt - visited[y][x][dir]);
        cnt += tmp;
        if (cnt == l)
          break;
      }

      int ny = y + dy[dir], nx = x + dx[dir];
      while (
          !(0 <= ny && ny < h && 0 <= nx && nx < w && cells[ny][nx] == empty)) {
        dir = rotate[dir];
        ny = y + dy[dir];
        nx = x + dx[dir];
      }
      y = ny;
      x = nx;
      ++cnt;
    }

    cout << y + 1 << ' ' << x + 1 << ' ' << "NESW"[dir] << endl;
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  Solve();
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define ALL(c) c.begin(), c.end()
#define RALL(c) c.rbegin(), c.rend()
#define SORT(x) sort((x).begin(), (x).end())
#define REP(i, x, y) for (int i = (x); i < (y); ++i)
#define MP(a, b) make_pair((a), (b))
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int, int> pii;
// template<typename T> using vec=std::vector<T>;

const int INF = 1 << 30;
const long long int INF_ = 1LL << 58;
const double EPS = 1e-9;

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

struct State {
  int y, x, dir;
};

void Solve() {
  while (true) {
    ll h, w, l;
    cin >> h >> w >> l;
    if (h == 0 && w == 0 && l == 0)
      break;
    vector<string> cells(h);
    REP(i, 0, h) cin >> cells[i];

    const char empty = '.', wall = '#';
    const int north = 0, east = 1, south = 2, west = 3;
    int y, x, dir;
    REP(i, 0, h) REP(j, 0, w) if (cells[i][j] != empty && cells[i][j] != wall) {
      y = i;
      x = j;
      switch (cells[i][j]) {
      case 'N':
        dir = north;
        break;
      case 'E':
        dir = east;
        break;
      case 'S':
        dir = south;
        break;
      case 'W':
        dir = west;
        break;
      default:
        break;
      }
      cells[i][j] = empty;
      break;
    }

    int rotate[4];
    REP(i, 0, 4) rotate[i] = (i + 1) % 4;

    // State memo[100][100][4];
    // REP(i,0,h) REP(j,0,w) REP(k,0,4){
    // int y_=i,x_=j;
    // int ny=y_+dy[k],nx=x_+dx[k];
    // while(0<=ny&&ny<h&&0<=nx&&nx<w&&cells[ny][nx]==empty){
    // y_=ny; x_=nx;
    // ny=y_+dy[k]; nx=x_+dx[k];
    //}
    // memo[i][j][k]={y_,x_,rotate[k]};
    //}

    const int dx[] = {0, 1, 0, -1}, dy[] = {-1, 0, 1, 0};
    ll visited[100][100][4];
    fill_n((ll *)visited, 100 * 100 * 4, -1);
    ll cnt = 0;
    while (cnt < l) {
      dump(y);
      dump(x);
      if (visited[y][x][dir] == -1)
        visited[y][x][dir] = cnt;
      else {
        cnt += ((l - cnt) / (cnt - visited[y][x][dir])) *
               (cnt - visited[y][x][dir]);
        if (cnt == l)
          break;
      }

      int ny = y + dy[dir], nx = x + dx[dir];
      while (
          !(0 <= ny && ny < h && 0 <= nx && nx < w && cells[ny][nx] == empty)) {
        dir = rotate[dir];
        ny = y + dy[dir];
        nx = x + dx[dir];
      }
      y = ny;
      x = nx;
      ++cnt;
    }

    cout << y + 1 << ' ' << x + 1 << ' ' << "NESW"[dir] << endl;
  }
}

int main() {
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  Solve();
  return 0;
}