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

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; ++i)
#define rep(i, n) REP(i, 0, n)

using namespace std;

#define MAX 51
int N, M;
string c[MAX];
bool visited[MAX][MAX][4];
bool path[MAX][MAX][4];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};

inline bool isValid(int x, int y) { return 0 <= x && x < M && 0 <= y && y < N; }

inline bool check(int x, int y) {
  rep(i, 4) if (path[y][x][i]) return true;
  return false;
}

struct Point {
  int x, y;
};

void normalize() {
  deque<Point> deq;
  rep(i, N) rep(j, M) {
    int cnt = 0;
    int dir = -1;
    rep(k, 4) {
      int nx = j + dx[k], ny = i + dy[k];
      if (!isValid(nx, ny))
        continue;
      if (c[ny][nx] == '#')
        continue;
      ++cnt;
      dir = k;
    }
    if (cnt == 1) {
      c[i][j] = '#';
      deq.push_back((Point){j + dx[dir], i + dy[dir]});
    }
  }
  while (!deq.empty()) {
    Point p = deq.front();
    deq.pop_front();
    int cnt = 0;
    int dir = -1;
    rep(i, 4) {
      int nx = p.x + dx[i], ny = p.y + dy[i];
      if (!isValid(nx, ny))
        continue;
      if (c[ny][nx] == '#')
        continue;
      ++cnt;
      dir = i;
    }
    if (cnt == 1) {
      c[p.y][p.x] = '#';
      deq.push_back((Point){p.x + dx[dir], p.y + dy[dir]});
    }
  }
}

bool dfs(int x, int y, int dir) {
  if (x == 1 && y == 0) {
    if (!check(M - 1, 0) || !check(0, N - 1) || !check(M - 1, N - 1))
      return false;
    return true;
  }
  rep(i, 4) {
    int xdir = (dir + i) % 4;
    int nx = x + dx[xdir], ny = y + dy[xdir], ndir = xdir;
    if (!isValid(nx, ny)) {
      nx = x, ny = y;
      (ndir += 1) %= 4;
    } else {
      if (c[ny][nx] == '#') {
        (ndir += 1) %= 4;
        nx = x, ny = y;
      } else {
        int lx = nx + dx[(ndir + 3) % 4], ly = ny + dy[(ndir + 3) % 4];
        if (isValid(lx, ly) && c[ly][lx] != '#')
          (ndir += 3) %= 4;
      }
    }
    if (!(x == nx && y == ny) && check(nx, ny))
      continue;
    if (visited[ny][nx][ndir])
      continue;
    visited[ny][nx][ndir] = true;
    path[ny][nx][ndir] = true;
    // return dfs(nx,ny,ndir);
    if (dfs(nx, ny, ndir))
      return true;
    path[ny][nx][ndir] = false;
  }
  return false;
}

bool compute() {
  // puts("--");
  // rep(i,N) cout << c[i] << endl;
  // puts("--");
  normalize();
  // rep(i,N) cout << c[i] << endl;
  // puts("");

  memset(visited, false, sizeof visited);
  memset(path, false, sizeof path);
  int x = 0, y = 0;
  int dir = 0;
  visited[0][0][0] = true;
  path[0][0][0] = true;
  return dfs(0, 0, 0);

  while (1) {
    int nx = x + dx[dir], ny = y + dy[dir], ndir = dir;
    if (!isValid(nx, ny)) {
      nx = x, ny = y;
      (ndir += 1) %= 4;
    } else {
      if (c[ny][nx] == '#') {
        (ndir += 1) %= 4;
        nx = x, ny = y;
      } else {
        int lx = nx + dx[(ndir + 3) % 4], ly = ny + dy[(ndir + 3) % 4];
        if (isValid(lx, ly) && c[ly][lx] != '#')
          (ndir += 3) %= 4;
      }
    }
    if (!(x == nx && y == ny) && check(nx, ny))
      break;
    if (visited[ny][nx][ndir])
      break;
    x = nx, y = ny, dir = ndir;
    visited[y][x][dir] = true;

    /*
    rep(i,N) {
      rep(j,M) {
        if( check(j,i) ) cout << "X";
        else cout << c[i][j];
      } puts("");
    } puts("");
    */
  }

  // cout << x << " and " << y << endl;
  if (!(x == 1 && y == 0))
    return false;
  if (!check(M - 1, 0) || !check(0, N - 1) || !check(M - 1, N - 1))
    return false;
  return true;
}

int main() {
  while (cin >> N >> M, N | M) {
    rep(i, N) cin >> c[i];
    puts(compute() ? "YES" : "NO");
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <climits>
#include <cstdio>
#include <cstring>
#include <deque>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <vector>

#define REP(i, s, n) for (int i = s; i < n; ++i)
#define rep(i, n) REP(i, 0, n)

using namespace std;

#define MAX 51
int N, M;
string c[MAX];
bool visited[MAX][MAX][4];
int dx[] = {0, 1, 0, -1};
int dy[] = {1, 0, -1, 0};

inline bool isValid(int x, int y) { return 0 <= x && x < M && 0 <= y && y < N; }

inline bool check(int x, int y) {
  rep(i, 4) if (visited[y][x][i]) return true;
  return false;
}

bool compute() {
  memset(visited, false, sizeof visited);
  int x = 0, y = 0;
  int dir = 0;
  visited[0][0][0] = true;
  while (1) {
    int nx = x + dx[dir], ny = y + dy[dir];
    if (!isValid(nx, ny)) {
      (dir += 1) %= 4;
      continue;
    } else {
      if (c[ny][nx] == '#') {
        (dir += 1) %= 4;
        continue;
      } else {
        x = nx, y = ny;
        int lx = x + dx[(dir + 3) % 4], ly = y + dy[(dir + 3) % 4];
        if (isValid(lx, ly) && c[ly][lx] != '#')
          (dir += 3) %= 4;
      }
    }
    if (check(x, y))
      break;
    visited[y][x][dir] = true;
  }
  if (!(x == 0 && y == 0))
    return false;
  if (!check(M - 1, 0) || !check(0, N - 1) || !check(M - 1, N - 1))
    return false;
  return true;
}

int main() {
  while (cin >> N >> M, N | M) {
    rep(i, N) cin >> c[i];
    puts(compute() ? "YES" : "NO");
  }
  return 0;
}