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

#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define ll long long
#define vvi vector<vector<int>>
#define vi vector<int>
#define All(X) X.begin(), X.end()
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define pb push_back
#define pii pair<int, int>
#define mp make_pair
#define pi 3.14159265359
#define shosu(X) fixed << setprecision(X)
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// x left to right
// y up to down
//(0,0) is left-up
int w, h;
int sx, sy, gx, gy;
struct G {
  int grid[20][20];
  int x, y;
};
G Data;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int ans = 114514;

bool isinrange(int x, int y) { return (x > -1 && y > -1 && x < w && y < h); }
int Simulate(int dir, G *gd) {
  int movecnt = 0;
  while (1) {
    gd->x += dx[dir];
    gd->y += dy[dir];
    if (!isinrange(gd->x, gd->y))
      return 0;

    if (gd->grid[gd->x][gd->y] == 1) {
      if (movecnt > 0) {
        gd->grid[gd->x][gd->y] = 0;
        gd->x -= dx[dir];
        gd->y -= dy[dir];
        return 1;
      } else {
        return 0;
      }
    } else {
      if (gd->x == gx && gd->y == gy)
        return 2;
    }
    movecnt++;
  }
}

void search(int cnt, G testgrid) {
  if (cnt == 10)
    return;
  REP(i, 4) {
    G bkgrid = testgrid;
    int rst = Simulate(i, &bkgrid);
    if (rst == 1) {
      search(cnt + 1, bkgrid);
    } else if (rst == 2) {
      ans = min(ans, cnt + 1);
    }
  }
}
int main() {
  while (1) {
    ans = 114514;
    cin >> w >> h;
    if (w == 0 && h == 0)
      break;
    REP(i, h) {
      REP(j, w) {
        cin >> Data.grid[j][i];
        if (Data.grid[j][i] == 2) {
          Data.grid[j][i] = 0;
          sx = j;
          sy = i;
        }
        if (Data.grid[j][i] == 3) {
          Data.grid[j][i] = 0;
          gx = j;
          gy = i;
        }
        Data.x = sx;
        Data.y = sy;
      }
    }
    search(0, Data);

    if (ans == 114514)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

#define ll long long
#define vvi vector<vector<int>>
#define vi vector<int>
#define All(X) X.begin(), X.end()
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define pb push_back
#define pii pair<int, int>
#define mp make_pair
#define pi 3.14159265359
#define shosu(X) fixed << setprecision(X)
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }
ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

// x left to right
// y up to down
//(0,0) is left-up
int w, h;
int sx, sy, gx, gy;
struct G {
  int grid[20][20];
  int x, y;
};
G Data;
int dx[4] = {-1, 0, 1, 0};
int dy[4] = {0, 1, 0, -1};
int ans = 114514;

bool isinrange(int x, int y) { return (x > -1 && y > -1 && x < w && y < h); }
int Simulate(int dir, G *gd) {
  int movecnt = 0;
  while (1) {
    gd->x += dx[dir];
    gd->y += dy[dir];
    if (!isinrange(gd->x, gd->y))
      return 0;

    if (gd->grid[gd->x][gd->y] == 1) {
      if (movecnt > 0)
        gd->grid[gd->x][gd->y] = 0;
      gd->x -= dx[dir];
      gd->y -= dy[dir];
      return 1;
    } else {
      if (gd->x == gx && gd->y == gy)
        return 2;
    }
    movecnt++;
  }
}

void search(int cnt, G testgrid) {
  if (cnt == 10)
    return;
  REP(i, 4) {
    G bkgrid = testgrid;
    int rst = Simulate(i, &bkgrid);
    if (rst == 1) {
      search(cnt + 1, bkgrid);
    } else if (rst == 2) {
      ans = cnt + 1;
    }
  }
}
int main() {
  while (1) {
    ans = 114514;
    cin >> w >> h;
    if (w == 0 && h == 0)
      break;
    REP(i, h) {
      REP(j, w) {
        cin >> Data.grid[j][i];
        if (Data.grid[j][i] == 2) {
          Data.grid[j][i] = 0;
          sx = j;
          sy = i;
        }
        if (Data.grid[j][i] == 3) {
          Data.grid[j][i] = 0;
          gx = j;
          gy = i;
        }
        Data.x = sx;
        Data.y = sy;
      }
    }
    search(0, Data);

    if (ans == 114514)
      cout << -1 << endl;
    else
      cout << ans << endl;
  }
}