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

#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#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 ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define INF 1e9

int W, H;
int start_x, start_y, goal_x, goal_y;
int *ices[12][12];
char maze[12][12];
bool G[12][12];
int depth;
int next_depth;

const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

void dfs_count(int *ice, int x, int y) {
  (*ice)++;
  ices[y][x] = ice;
  maze[y][x] = '?'; // used

  REP(i, 4) {
    int sx = x + dx[i], sy = y + dy[i];
    if (0 <= sx && sx < W && 0 <= sy && sy < H) {
      if (maze[sy][sx] == 'X') {
        dfs_count(ice, sx, sy);
      }
    }
  }
}

bool iddfs(int x, int y, int step) {
  if (x == goal_x && y == goal_y)
    return true;
  int dist = abs(x - goal_x) + abs(y - goal_y);
  if (step + dist > depth) {
    next_depth = min(next_depth, step + dist);
    return false;
  }
  REP(i, 4) {
    int sx = x + dx[i], sy = y + dy[i];
    if (0 <= sx && sx < W && 0 <= sy && sy < H) {
      if (*ices[sy][sx] > 0 && !G[sy][sx]) {
        (*ices[sy][sx])--;
        G[sy][sx] = true;
        if (iddfs(sx, sy, step + 1))
          return true;
        G[sy][sx] = false;
        (*ices[sy][sx])++;
      }
    }
  }
  return false;
}

int main() {
  while (cin >> W >> H, W | H) {
    REP(y, H) REP(x, W) cin >> maze[y][x];

    int empty = 100000;
    int wall = 0;

    int ice[12][12] = {};

    REP(y, H) REP(x, W) {
      switch (maze[y][x]) {
      case '.':
        ices[y][x] = &empty;
        break;
      case '#':
        ices[y][x] = &wall;
        break;
      case 'S':
        start_x = x;
        start_y = y;
        ices[y][x] = &empty;
        break;
      case 'G':
        goal_x = x;
        goal_y = y;
        ices[y][x] = &empty;
        break;
      case 'X': {
        dfs_count(&ice[y][x], x, y);
        ice[y][x] /= 2;
        ices[y][x] = &ice[y][x];
        break;
      }
      }
      maze[y][x] = '?'; // used
    }

    fill_n((bool *)G, 12 * 12, false);
    depth = abs(start_x - goal_x) + abs(start_y - goal_y);
    while (!iddfs(start_x, start_y, 0)) {
      depth = next_depth;
      next_depth = INF;
    }
    cout << depth << endl;
  }
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#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 ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define INF 1e9

int W, H;
int start_x, start_y, goal_x, goal_y;
int *ices[12][12];
char maze[12][12];
bool G[12][12];
int depth;
int next_depth;

const int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};

void dfs_count(int *ice, int x, int y) {
  (*ice)++;
  ices[y][x] = ice;
  maze[y][x] = '?'; // used

  REP(i, 4) {
    int sx = x + dx[i], sy = y + dy[i];
    if (0 <= sx && sx < W && 0 <= sy && sy < H) {
      if (maze[sy][sx] == 'X') {
        dfs_count(ice, sx, sy);
      }
    }
  }
}

bool iddfs(int x, int y, int step) {
  if (x == goal_x && y == goal_y)
    return true;
  if (step == depth) {
    next_depth = min(next_depth, depth + abs(x - goal_x) + abs(y - goal_y));
    return false;
  }
  REP(i, 4) {
    int sx = x + dx[i], sy = y + dy[i];
    if (0 <= sx && sx < W && 0 <= sy && sy < H) {
      if (*ices[sy][sx] > 0 && !G[sy][sx]) {
        (*ices[sy][sx])--;
        G[sy][sx] = true;
        if (iddfs(sx, sy, step + 1))
          return true;
        G[sy][sx] = false;
        (*ices[sy][sx])++;
      }
    }
  }
  return false;
}

int main() {
  while (cin >> W >> H, W | H) {
    REP(y, H) REP(x, W) cin >> maze[y][x];

    int empty = 100000;
    int wall = 0;

    int ice[12][12] = {};

    REP(y, H) REP(x, W) {
      switch (maze[y][x]) {
      case '.':
        ices[y][x] = &empty;
        break;
      case '#':
        ices[y][x] = &wall;
        break;
      case 'S':
        start_x = x;
        start_y = y;
        ices[y][x] = &empty;
        break;
      case 'G':
        goal_x = x;
        goal_y = y;
        ices[y][x] = &empty;
        break;
      case 'X': {
        dfs_count(&ice[y][x], x, y);
        ice[y][x] /= 2;
        ices[y][x] = &ice[y][x];
        break;
      }
      }
      maze[y][x] = '?'; // used
    }

    fill_n((bool *)G, 12 * 12, false);
    depth = abs(start_x - goal_x) + abs(start_y - goal_y);
    while (!iddfs(start_x, start_y, 0)) {
      depth = next_depth;
      next_depth = INF;
    }
    cout << depth << endl;
  }
}