Problem p00725 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>

// 0 : space 1 : twall 2 : start 3 : goal 4 : wall
int board[32][32];
int W, H;

void init() {
  for (int i = 0; i < (int)32; ++i) {
    for (int j = 0; j < (int)32; ++j) {
      board[i][j] = 4;
    }
  }
}

void Load() {
  scanf("%d %d", &W, &H);
  for (int i = 0; i < (int)H; ++i) {
    for (int j = 0; j < (int)W; ++j) {
      scanf("%d", &board[i + 1][j + 1]);
    }
  }
}

int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};

class Solve_ {
  std::pair<int, int> start, end;
  int dist[32][32][4];
  int limit;
  bool ok;

public:
  int operator()() {
    init();
    ok = false;
    int res = (1 << 29);
    for (limit = 1; limit < 441; ++limit) {
      dfs(start, 0);
      if (ok) {
        res = limit;
        break;
      }
    }
    if (res >= 11)
      res = -1;
    return res;
  }
  void dfs(std::pair<int, int> p, int d) {
    if (d >= limit)
      return;
    int r = p.first, c = p.second;
    if (board[r][c] == 3)
      return;
    for (int k = 0; k < 4; ++k) {
      int nr = r + dr[k], nc = c + dc[k];
      if (board[nr][nc] == 1 or board[nr][nc] == 4)
        continue;
      if (nr == end.first and nc == end.second) {
        ok = true;
        return;
      }
      for (;;) {
        int nnr = nr + dr[k], nnc = nc + dc[k];
        if (board[nnr][nnc] == 1 or board[nnr][nnc] == 4)
          break;
        nr = nnr;
        nc = nnc;
        if (nr == end.first and nc == end.second) {
          ok = true;
          return;
        }
      }
      if (board[nr + dr[k]][nc + dc[k]] == 4)
        continue;
      // if( dist[nr][nc][k] <= d + 1 ) continue;
      dist[nr][nc][k] = d + 1;
      bool b = false;
      if (board[nr + dr[k]][nc + dc[k]] == 1) {
        b = true;
      }
      if (b) {
        board[nr + dr[k]][nc + dc[k]] = 0;
      }
      dfs(std::pair<int, int>(nr, nc), d + 1);
      if (b) {
        board[nr + dr[k]][nc + dc[k]] = 1;
      }
      if (ok)
        break;
    }
  }
  void init() {
    for (int i = 1; i <= H; ++i) {
      for (int j = 1; j <= W; ++j) {
        if (board[i][j] == 2) {
          start = std::pair<int, int>(i, j);
        }
        if (board[i][j] == 3) {
          end = std::pair<int, int>(i, j);
        }
      }
    }
    for (int i = 0; i < 32; ++i) {
      for (int j = 0; j < 32; ++j) {
        for (int k = 0; k < 4; ++k) {
          dist[i][j][k] = (1 << 29);
        }
      }
    }
  }
};
Solve_ Solve;

int main() {
  for (;;) {
    init();
    Load();
    if (W == 0 and H == 0)
      break;
    int res = Solve();
    printf("%d\n", res);
  }

  return 0;
}

Fixed submission:
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <string>
#include <vector>

// 0 : space 1 : twall 2 : start 3 : goal 4 : wall
int board[32][32];
int W, H;

void init() {
  for (int i = 0; i < (int)32; ++i) {
    for (int j = 0; j < (int)32; ++j) {
      board[i][j] = 4;
    }
  }
}

void Load() {
  scanf("%d %d", &W, &H);
  for (int i = 0; i < (int)H; ++i) {
    for (int j = 0; j < (int)W; ++j) {
      scanf("%d", &board[i + 1][j + 1]);
    }
  }
}

int dr[4] = {1, 0, -1, 0};
int dc[4] = {0, 1, 0, -1};

class Solve_ {
  std::pair<int, int> start, end;
  int dist[32][32][4];
  int limit;
  bool ok;

public:
  int operator()() {
    init();
    ok = false;
    int res = (1 << 29);
    for (limit = 1; limit < 11; ++limit) {
      dfs(start, 0);
      if (ok) {
        res = limit;
        break;
      }
    }
    if (res >= 11)
      res = -1;
    return res;
  }
  void dfs(std::pair<int, int> p, int d) {
    if (d >= limit)
      return;
    int r = p.first, c = p.second;
    if (board[r][c] == 3)
      return;
    for (int k = 0; k < 4; ++k) {
      int nr = r + dr[k], nc = c + dc[k];
      if (board[nr][nc] == 1 or board[nr][nc] == 4)
        continue;
      if (nr == end.first and nc == end.second) {
        ok = true;
        return;
      }
      for (;;) {
        int nnr = nr + dr[k], nnc = nc + dc[k];
        if (board[nnr][nnc] == 1 or board[nnr][nnc] == 4)
          break;
        nr = nnr;
        nc = nnc;
        if (nr == end.first and nc == end.second) {
          ok = true;
          return;
        }
      }
      if (board[nr + dr[k]][nc + dc[k]] == 4)
        continue;
      // if( dist[nr][nc][k] <= d + 1 ) continue;
      dist[nr][nc][k] = d + 1;
      bool b = false;
      if (board[nr + dr[k]][nc + dc[k]] == 1) {
        b = true;
      }
      if (b) {
        board[nr + dr[k]][nc + dc[k]] = 0;
      }
      dfs(std::pair<int, int>(nr, nc), d + 1);
      if (b) {
        board[nr + dr[k]][nc + dc[k]] = 1;
      }
      if (ok)
        break;
    }
  }
  void init() {
    for (int i = 1; i <= H; ++i) {
      for (int j = 1; j <= W; ++j) {
        if (board[i][j] == 2) {
          start = std::pair<int, int>(i, j);
        }
        if (board[i][j] == 3) {
          end = std::pair<int, int>(i, j);
        }
      }
    }
    for (int i = 0; i < 32; ++i) {
      for (int j = 0; j < 32; ++j) {
        for (int k = 0; k < 4; ++k) {
          dist[i][j][k] = (1 << 29);
        }
      }
    }
  }
};
Solve_ Solve;

int main() {
  for (;;) {
    init();
    Load();
    if (W == 0 and H == 0)
      break;
    int res = Solve();
    printf("%d\n", res);
  }

  return 0;
}