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

#include <iostream>
#include <map>
#include <vector>
using namespace std;

#define WALL '#'
#define EMPTY '.'

enum { NORTH, EAST, SOUTH, WEST };
char ItoC[4] = {'N', 'E', 'S', 'W'};
map<char, int> CtoI;

int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};

struct Robot {
  int y, x, dir;

  Robot(int i = 0, int j = 0, int d = 0) {
    y = i;
    x = j;
    dir = d;
  }

  void move() {
    y += dy[dir];
    x += dx[dir];
  }
  void turn() { dir = (dir + 1) % 4; }

  bool operator<(Robot r) const {
    return y != r.y ? y < r.y : (x != r.x ? x < r.x : dir < r.dir);
  }
};

int main() {
  CtoI['N'] = 0;
  CtoI['E'] = 1;
  CtoI['S'] = 2;
  CtoI['W'] = 3;
  long long int H, W, L;
  while (cin >> H >> W >> L, H | W | L) {
    vector<vector<char>> c(H + 2, vector<char>(W + 2, WALL));
    Robot me;
    long long int step = 0;
    map<Robot, int> visited;
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        cin >> c[i][j];
        if (c[i][j] != WALL && c[i][j] != EMPTY) {
          me = Robot(i, j, CtoI[c[i][j]]);
          c[i][j] = EMPTY;
        }
      }
    }

    while (L > step) {
      while (c[me.y + dy[me.dir]][me.x + dx[me.dir]] == WALL) {
        me.turn();
      }
      me.move();
      step++;
      if (visited.count(me)) {
        long long int dif = step - visited[me];
        step = L - (L - step) % dif;
      } else {
        visited[me] = step;
      }
    }

    cout << me.y << " " << me.x << " " << ItoC[me.dir] << endl;
  }
}

Error: TLE

Fixed submission:


#include <iostream>
#include <map>
#include <vector>
using namespace std;

#define WALL '#'
#define EMPTY '.'

enum { NORTH, EAST, SOUTH, WEST };
char ItoC[4] = {'N', 'E', 'S', 'W'};
map<char, int> CtoI;

int dx[4] = {0, 1, 0, -1};
int dy[4] = {-1, 0, 1, 0};

struct Robot {
  int y, x, dir;

  Robot(int i = 0, int j = 0, int d = 0) {
    y = i;
    x = j;
    dir = d;
  }

  void move() {
    y += dy[dir];
    x += dx[dir];
  }
  void turn() { dir = (dir + 1) % 4; }

  bool operator<(Robot r) const {
    return y != r.y ? y < r.y : (x != r.x ? x < r.x : dir < r.dir);
  }
};

int main() {
  CtoI['N'] = 0;
  CtoI['E'] = 1;
  CtoI['S'] = 2;
  CtoI['W'] = 3;
  long long int H, W, L;
  while (cin >> H >> W >> L, H | W | L) {
    vector<vector<char>> c(H + 2, vector<char>(W + 2, WALL));
    Robot me;
    long long int step = 0;
    map<Robot, int> visited;
    for (int i = 1; i <= H; i++) {
      for (int j = 1; j <= W; j++) {
        cin >> c[i][j];
        if (c[i][j] != WALL && c[i][j] != EMPTY) {
          me = Robot(i, j, CtoI[c[i][j]]);
          c[i][j] = EMPTY;
        }
      }
    }

    // for(int i=0; i<=H+1; i++){
    //   for(int j=0; j<=W+1; j++){
    //     cout<<" "<<c[i][j];
    //   }
    //   cout<<endl;
    // }

    while (L > step) {
      while (c[me.y + dy[me.dir]][me.x + dx[me.dir]] == WALL) {
        me.turn();
      }
      if (visited.count(me)) {
        long long int t = step - visited[me];
        step = L - L % t;
        // cout<<"+"<<endl;
      } else {
        visited[me] = step;
      }
      step++;
      me.move();
      // cout<<step<<endl;
      // cout<<me.y<<" "<<me.x<<" "<<ItoC[me.dir]<<endl;
    }

    cout << me.y << " " << me.x << " " << ItoC[me.dir] << endl;
  }
}