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

#include "bits/stdc++.h"
using namespace std;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2612&lang=jp
#define INF 1 << 30
#define H 19
#define W 15
typedef long long ll;
typedef pair<int, int> pii;
int ans = INF;
int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};

bool check(int x, int y, vector<vector<char>> &masu, int &dir) {
  int nx = x + dx[dir], ny = y + dy[dir];
  if (masu[nx][ny] != 'X')
    return false;
  while (true) {
    nx += dx[dir];
    ny += dy[dir];
    if (masu[nx][ny] == 'X')
      continue;
    if (masu[nx][ny] == '#')
      return false;
    if (masu[nx][ny] == '.')
      return true;
  }
  return false;
}

void erase_move(int &x, int &y, vector<vector<char>> &masu, int &dir) {
  while (true) {
    x += dx[dir];
    y += dy[dir];
    if (masu[x][y] == 'X') {
      masu[x][y] = '.';
      continue;
    }
    if (masu[x][y] == '.')
      return;
  }
}

void dfs(int x, int y, int cnt, vector<vector<char>> &masu) {
  if (cnt + 1 >= ans)
    return;
  for (int dir = 0; dir < 8; dir++) {
    if (!check(x, y, masu, dir))
      continue;
    auto new_masu = masu;
    int new_x = x, new_y = y;
    erase_move(new_x, new_y, new_masu, dir);

    if (new_x >= 19) {
      ans = min(ans, cnt + 1);
      return;
    }

    dfs(new_x, new_y, cnt + 1, new_masu);
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  vector<vector<char>> masu(H + 2, vector<char>(W + 2, '#'));
  int sx, sy;
  /* input */
  masu[H + 1][0] = masu[H + 1][W + 1] = '.';
  for (int i = 1; i <= H + 1; i++) {
    for (int j = 1; j <= W; j++) {
      if (i == H + 1)
        masu[i][j] = '.';
      else {
        cin >> masu[i][j];
        if (masu[i][j] == 'O') {
          sx = i;
          sy = j;
          masu[i][j] = '.';
        }
      }
    }
  }

  int f = 0;
  for (int i = sx + 1; i <= H; i++) {
    for (int j = 1; j <= W; j++) {
      if (masu[i][j] == 'X') {
        f = 0;
        break;
      }
      if (j == W)
        f++;
    }
    if (f == 2) {
      cout << -1 << endl;
      return 0;
    }
  }

  dfs(sx, sy, 0, masu);
  cout << (ans == INF ? -1 : ans) << endl;
  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;
// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2612&lang=jp
#define INF 1 << 30
#define H 19
#define W 15
typedef long long ll;
typedef pair<int, int> pii;
int ans = INF;
int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
int dy[8] = {0, -1, -1, -1, 0, 1, 1, 1};

bool check(int x, int y, vector<vector<char>> &masu, int &dir) {
  int nx = x + dx[dir], ny = y + dy[dir];
  if (masu[nx][ny] != 'X')
    return false;
  while (true) {
    nx += dx[dir];
    ny += dy[dir];
    if (masu[nx][ny] == 'X')
      continue;
    if (masu[nx][ny] == '#')
      return false;
    if (masu[nx][ny] == '.')
      return true;
  }
  return false;
}

void erase_move(int &x, int &y, vector<vector<char>> &masu, int &dir) {
  while (true) {
    x += dx[dir];
    y += dy[dir];
    if (masu[x][y] == 'X') {
      masu[x][y] = '.';
      continue;
    }
    if (masu[x][y] == '.')
      return;
  }
}

void dfs(int x, int y, int cnt, vector<vector<char>> &masu) {
  if (cnt + 1 >= ans)
    return;
  for (int dir = 0; dir < 8; dir++) {
    if (!check(x, y, masu, dir))
      continue;
    auto new_masu = masu;
    int new_x = x, new_y = y;
    erase_move(new_x, new_y, new_masu, dir);

    if (new_x >= 19) {
      ans = min(ans, cnt + 1);
      return;
    }

    dfs(new_x, new_y, cnt + 1, new_masu);
  }
}

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  vector<vector<char>> masu(H + 2, vector<char>(W + 2, '#'));
  int sx, sy;
  /* input */
  masu[H + 1][0] = masu[H + 1][W + 1] = '.';
  for (int i = 1; i <= H + 1; i++) {
    for (int j = 1; j <= W; j++) {
      if (i == H + 1)
        masu[i][j] = '.';
      else {
        cin >> masu[i][j];
        if (masu[i][j] == 'O') {
          sx = i;
          sy = j;
          masu[i][j] = '.';
        }
      }
    }
  }
  dfs(sx, sy, 0, masu);
  cout << (ans == INF ? -1 : ans) << endl;
  return 0;
}