Problem p01437 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-10;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
typedef int Weight;
struct Edge {
  int from, to;
  Weight cost;
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, int cost) {
  g[from].push_back(Edge{from, to, cost});
}
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
int place(int x, int y, int dir, int h, int w) {
  return dir * h * w + w * x + y;
}

/*--------------------template--------------------*/

vi rev(int p, int h, int w) {
  //(dir*h+x)*w+y
  int y = p % w;
  p = (p - y) / w;
  int x = p % h;
  int dir = (p - x) / h;
  vi v = {x, y, dir};
  return v;
}

int main() {
  ll h, w, l;
  while (cin >> h >> w >> l, h) {
    Graph g(h * w * 4);
    vs fld(h);
    REP(i, h) cin >> fld[i];
    int st;
    REP(i, h) REP(j, w) {
      if (fld[i][j] == 'N')
        st = place(i, j, 0, h, w);
      if (fld[i][j] == 'E')
        st = place(i, j, 1, h, w);
      if (fld[i][j] == 'S')
        st = place(i, j, 2, h, w);
      if (fld[i][j] == 'W')
        st = place(i, j, 3, h, w);
      if (fld[i][j] != '.' && fld[i][j] != '#')
        fld[i][j] = '.';
    }
    REP(dir, 4) REP(i, h) REP(j, w) {
      if (fld[i][j] == '#')
        continue;
      int k = 0, cnt = 0;
      int nx = i + dx[dir], ny = j + dy[dir];
      for (; !valid(nx, ny, h, w) || fld[nx][ny] == '#';) {
        k++;
        cnt++;
        if (cnt > 10)
          goto next;
        k %= 4;
        nx = i + dx[(dir + k) % 4];
        ny = j + dy[(dir + k) % 4];
      }
      add_edge(g, place(i, j, dir, h, w), place(nx, ny, (dir + k) % 4, h, w),
               1);
    next:;
    }
    set<int> memo;
    vi v;
    int loop;
    memo.insert(st);
    v.push_back(st);
    while (1) {
      int tmp = v.back();
      int next = g[tmp][0].to;
      if (memo.find(next) != memo.end()) {
        loop = next;
        break;
      }
      memo.insert(next);
      v.push_back(next);
    }
    int ans;
    if (v.size() > l)
      ans = v[l];
    else {
      int beg = find(ALL(v), loop) - v.begin();
      int len = v.size() - beg;
      l -= beg;
      ans = v[beg + l % len];
    }
    vi ansv = rev(ans, h, w);
    int ax = ansv[0] + 1, ay = ansv[1] + 1;
    char ad;
    switch (ansv[2]) {
    case 0:
      ad = 'N';
      break;
    case 1:
      ad = 'E';
      break;
    case 2:
      ad = 'S';
      break;
    case 3:
      ad = 'W';
      break;
    }
    cout << ax << " " << ay << " " << ad << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, k, n) for (int i = (k); i < (n); i++)
#define REP(i, n) FOR(i, 0, n)
#define ALL(a) a.begin(), a.end()
#define MS(m, v) memset(m, v, sizeof(m))
#define D10 fixed << setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
typedef long double ld;
const int MOD = 1000000007;
const int INF = MOD + 1;
const ld EPS = 1e-10;
template <class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
typedef int Weight;
struct Edge {
  int from, to;
  Weight cost;
  bool operator<(const Edge &e) const { return cost < e.cost; }
  bool operator>(const Edge &e) const { return cost > e.cost; }
};
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
typedef vector<Weight> Array;
typedef vector<Array> Matrix;
void add_edge(Graph &g, int from, int to, int cost) {
  g[from].push_back(Edge{from, to, cost});
}
int dx[] = {-1, 0, 1, 0};
int dy[] = {0, 1, 0, -1};
bool valid(int x, int y, int h, int w) {
  return (x >= 0 && y >= 0 && x < h && y < w);
}
int place(int x, int y, int dir, int h, int w) {
  return dir * h * w + w * x + y;
}

/*--------------------template--------------------*/

vi rev(int p, int h, int w) {
  //(dir*h+x)*w+y
  int y = p % w;
  p = (p - y) / w;
  int x = p % h;
  int dir = (p - x) / h;
  vi v = {x, y, dir};
  return v;
}

int main() {
  ll h, w, l;
  while (cin >> h >> w >> l, h) {
    Graph g(h * w * 4);
    vs fld(h);
    REP(i, h) cin >> fld[i];
    int st;
    REP(i, h) REP(j, w) {
      if (fld[i][j] == 'N')
        st = place(i, j, 0, h, w);
      if (fld[i][j] == 'E')
        st = place(i, j, 1, h, w);
      if (fld[i][j] == 'S')
        st = place(i, j, 2, h, w);
      if (fld[i][j] == 'W')
        st = place(i, j, 3, h, w);
      if (fld[i][j] != '.' && fld[i][j] != '#')
        fld[i][j] = '.';
    }
    REP(dir, 4) REP(i, h) REP(j, w) {
      if (fld[i][j] == '#')
        continue;
      int k = 0, cnt = 0;
      int nx = i + dx[dir], ny = j + dy[dir];
      for (; !valid(nx, ny, h, w) || fld[nx][ny] == '#';) {
        cnt++;
        if (cnt > 100)
          return 1;
        k++;
        k %= 4;
        nx = i + dx[(dir + k) % 4];
        ny = j + dy[(dir + k) % 4];
      }
      add_edge(g, place(i, j, dir, h, w), place(nx, ny, (dir + k) % 4, h, w),
               1);
    }
    set<int> memo;
    vi v;
    int loop;
    memo.insert(st);
    v.push_back(st);
    while (1) {
      int tmp = v.back();
      int next = g[tmp][0].to;
      if (memo.find(next) != memo.end()) {
        loop = next;
        break;
      }
      memo.insert(next);
      v.push_back(next);
    }
    int ans;
    if (v.size() > l)
      ans = v[l];
    else {
      int beg = find(ALL(v), loop) - v.begin();
      int len = v.size() - beg;
      l -= beg;
      ans = v[beg + l % len];
    }
    vi ansv = rev(ans, h, w);
    int ax = ansv[0] + 1, ay = ansv[1] + 1;
    char ad;
    switch (ansv[2]) {
    case 0:
      ad = 'N';
      break;
    case 1:
      ad = 'E';
      break;
    case 2:
      ad = 'S';
      break;
    case 3:
      ad = 'W';
      break;
    }
    cout << ax << " " << ay << " " << ad << endl;
  }
  return 0;
}