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

#include <algorithm>
#include <iostream>
#define MAX 23

using namespace std;

int ans;
bool unreached = true;

void movestone(int counter, int d, int x, int y, int p[MAX][MAX]) {

  if (counter > 10) {
    return;
  }

  int temp[MAX][MAX];
  int nextx, nexty;
  nextx = x;
  nexty = y;

  // 1マス移動
  if (d == 0) {
    x--;
    nextx = x - 1;
  } else if (d == 1) {
    y--;
    nexty = y - 1;
  } else if (d == 2) {
    x++;
    nextx = x + 1;
  } else if (d = 3) {
    y++;
    nexty = y + 1;
  }

  // ゴール判定
  if (p[y][x] == 3) {
    ans = min(ans, counter);
    unreached = false;
    return;
  }

  // 岩に衝突した場合
  if (p[nexty][nextx] == 1) {
    for (int i = 0; i < MAX; i++) {
      for (int j = 0; j < MAX; j++) {
        temp[i][j] = p[i][j];
      }
    }
    temp[nexty][nextx] = 0;
    counter++;
    if (temp[y][x - 1] != 1 && temp[y][x - 1] != -1) {
      movestone(counter, 0, x, y, temp);
    }
    if (temp[y - 1][x] != 1 && temp[y - 1][x] != -1) {
      movestone(counter, 1, x, y, temp);
    }
    if (temp[y][x + 1] != 1 && temp[y][x + 1] != -1) {
      movestone(counter, 2, x, y, temp);
    }
    if (temp[y + 1][x] != 1 && temp[y + 1][x] != -1) {
      movestone(counter, 3, x, y, temp);
    }
  }

  // 何もなかった場合
  else if (p[nexty][nextx] != -1) {
    movestone(counter, d, x, y, p);
  }
}

int main() {
  int w, h, startx, starty, p[MAX][MAX];
  while (cin >> w >> h, w || h) {

    // 初期化
    ans = 100;
    unreached = true;
    for (int i = 0; i < MAX; i++) {
      for (int j = 0; j < MAX; j++) {
        p[i][j] = -1;
      }
    }

    // 入力
    for (int i = 1; i < h + 1; i++) {
      for (int j = 1; j < w + 1; j++) {
        cin >> p[i][j];
        if (p[i][j] == 2) {
          startx = j;
          starty = i;
        }
      }
    }

    // 移動させる
    if (p[starty][startx - 1] != 1 && p[starty][startx - 1] != -1) {
      movestone(1, 0, startx, starty, p);
    }
    if (p[starty - 1][startx] != 1 && p[starty - 1][startx] != -1) {
      movestone(1, 1, startx, starty, p);
    }
    if (p[starty][startx + 1] != 1 && p[starty][startx + 1] != -1) {
      movestone(1, 2, startx, starty, p);
    }
    if (p[starty + 1][startx] != 1 && p[starty + 1][startx] != -1) {
      movestone(1, 3, startx, starty, p);
    }

    // 移動終了
    if (unreached) {
      cout << -1 << endl;
    } else {
      cout << ans << endl;
    }
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#define MAX 100

using namespace std;

int ans;
bool unreached = true;

void movestone(int counter, int d, int x, int y, int p[MAX][MAX]) {
  if (counter > 10) {
    return;
  }

  int temp[MAX][MAX];
  int nextx, nexty;
  nextx = x;
  nexty = y;

  // 1マス移動
  if (d == 0) {
    x--;
    nextx = x - 1;
  } else if (d == 1) {
    y--;
    nexty = y - 1;
  } else if (d == 2) {
    x++;
    nextx = x + 1;
  } else if (d = 3) {
    y++;
    nexty = y + 1;
  }

  // ゴール判定
  if (p[y][x] == 3) {
    ans = min(ans, counter);
    unreached = false;
    return;
  }

  // 岩に衝突した場合
  if (p[nexty][nextx] == 1) {
    p[nexty][nextx] = 0;
    counter++;
    for (int i = 0; i < MAX; i++) {
      for (int j = 0; j < MAX; j++) {
        temp[i][j] = p[i][j];
      }
    }
    if (p[y][x - 1] != 1 && p[y][x - 1] != -1) {
      movestone(counter, 0, x, y, temp);
    }
    if (p[y - 1][x] != 1 && p[y - 1][x] != -1) {
      movestone(counter, 1, x, y, temp);
    }
    if (p[y][x + 1] != 1 && p[y][x + 1] != -1) {
      movestone(counter, 2, x, y, temp);
    }
    if (p[y + 1][x] != 1 && p[y + 1][x] != -1) {
      movestone(counter, 3, x, y, temp);
    }
  }

  // 何もなかった場合
  else if (p[nexty][nextx] != -1) {
    movestone(counter, d, x, y, p);
  }
}

int main() {
  int w, h, startx, starty, p[MAX][MAX];
  while (cin >> w >> h, w || h) {

    // 初期化
    ans = 100;
    unreached = true;
    for (int i = 0; i < MAX; i++) {
      for (int j = 0; j < MAX; j++) {
        p[i][j] = -1;
      }
    }

    // 入力
    for (int i = 1; i < h + 1; i++) {
      for (int j = 1; j < w + 1; j++) {
        cin >> p[i][j];
        if (p[i][j] == 2) {
          startx = j;
          starty = i;
        }
      }
    }

    // 移動させる
    if (p[starty][startx - 1] != 1 && p[starty][startx - 1] != -1) {
      movestone(1, 0, startx, starty, p);
    }
    if (p[starty - 1][startx] != 1 && p[starty - 1][startx] != -1) {
      movestone(1, 1, startx, starty, p);
    }
    if (p[starty][startx + 1] != 1 && p[starty][startx + 1] != -1) {
      movestone(1, 2, startx, starty, p);
    }
    if (p[starty + 1][startx] != 1 && p[starty + 1][startx] != -1) {
      movestone(1, 3, startx, starty, p);
    }

    // 移動終了
    if (unreached) {
      cout << -1 << endl;
    } else {
      cout << ans << endl;
    }
  }
  return 0;
}