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

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <stdexcept>
#include <vector>

using namespace std;

struct Vec2 {
  int x, y;
};

struct RobotState {
  Vec2 pos;
  int dir; // 0, 1, 2, 3
};

Vec2 dd[] = {{0, -1}, {1, 0}, {0, 1}, {-1, 0}};

void DirectToEmptyCell(const vector<vector<char>> &maze, RobotState &robot) {
  while (maze[robot.pos.y + dd[robot.dir].y][robot.pos.x + dd[robot.dir].x] ==
         '#') {
    robot.dir = (robot.dir + 1) % 4;
  }
}

void GoForward(RobotState &robot) {
  auto d = dd[robot.dir];
  robot.pos.x += d.x;
  robot.pos.y += d.y;
}

int DirCharToInt(char c) {
  switch (c) {
  case 'N':
    return 0;
  case 'E':
    return 1;
  case 'S':
    return 2;
  case 'W':
    return 3;
  default:
    throw logic_error("unko");
  }
}

char DirIntToChar(int dir) {
  static const char m[] = {'N', 'E', 'S', 'W'};
  return m[dir];
}

int main() {
  int H, W;
  long long L;
  while (cin >> H >> W >> L, H || W || L) {
    vector<vector<char>> maze(H + 2, vector<char>(W + 2, '#'));
    long long visited[102][102][4];
    for (size_t i = 0; i < 102; i++)
      for (size_t j = 0; j < 102; j++)
        for (size_t k = 0; k < 4; k++) {
          visited[i][j][k] = -1;
        }
    RobotState robot;
    // input maze
    for (int i = 1; i < H + 1; ++i) {
      for (int j = 1; j < W + 1; ++j) {
        char c;
        cin >> c;
        if (c == '.' || c == '#') {
          maze[i][j] = c;
        } else {
          maze[i][j] = '.';
          robot.pos.x = j;
          robot.pos.y = i;
          robot.dir = DirCharToInt(c);
        }
      }
    }
    // do this
    for (long long i = 0; i < L; ++i) {
      // detect loop
      auto &n = visited[robot.pos.y][robot.pos.x][robot.dir];
      if (n != -1) {
        i = L - (L - i) % (i - n);
        if (i == L) {
          break;
        }
      } else {
        n = i;
      }

      DirectToEmptyCell(maze, robot);
      GoForward(robot);
    }
    cout << robot.pos.y << ' ' << robot.pos.x << ' ' << DirIntToChar(robot.dir)
         << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <vector>

using namespace std;

struct robot_state {
  int x;
  int y;
  char orientation;
};

void orient_to_empty_cell(const vector<vector<char>> &maze,
                          robot_state &robot) {
  while (true) {
    switch (robot.orientation) {
    case 'N':
      if (maze[robot.y - 1][robot.x] == '#') {
        robot.orientation = 'E';
      } else {
        return;
      }
      break;
    case 'E':
      if (maze[robot.y][robot.x + 1] == '#') {
        robot.orientation = 'S';
      } else {
        return;
      }
      break;
    case 'S':
      if (maze[robot.y + 1][robot.x] == '#') {
        robot.orientation = 'W';
      } else {
        return;
      }
      break;
    case 'W':
      if (maze[robot.y][robot.x - 1] == '#') {
        robot.orientation = 'N';
      } else {
        return;
      }
      break;
    default:
      exit(EXIT_FAILURE);
      break;
    }
  }
}

void go_forward(robot_state &robot) {
  switch (robot.orientation) {
  case 'N':
    --robot.y;
    break;
  case 'E':
    ++robot.x;
    break;
  case 'S':
    ++robot.y;
    break;
  case 'W':
    --robot.x;
    break;
  default:
    exit(EXIT_FAILURE);
    break;
  }
}

int main() {
  int H, W;
  long long L;
  while (cin >> H >> W >> L, H || W || L) {
    vector<vector<char>> maze(H + 2, vector<char>(W + 2, '#'));
    robot_state robot;
    // input maze
    for (int i = 1; i < H + 1; ++i) {
      for (int j = 1; j < W + 1; ++j) {
        char c;
        cin >> c;
        if (c == '.' || c == '#') {
          maze[i][j] = c;
        } else {
          maze[i][j] = '.';
          robot.x = j;
          robot.y = i;
          robot.orientation = c;
        }
      }
    }
    // do this
    for (long long i = 0; i < L; ++i) {
      orient_to_empty_cell(maze, robot);
      go_forward(robot);
    }
    cout << robot.y << ' ' << robot.x << ' ' << robot.orientation << endl;
  }

  return 0;
}