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

#include <algorithm>
#include <cstring>
#include <iostream>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

int w, h, sy, sx, gy, gx;
char g[20][20];
int ice[20][20], num[10000], n;
int dis[20][20], ans;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, 1, 0, -1};
const int INF = 1000000;

void group(int y, int x, int c) {
  num[c]++;
  ice[y][x] = c;

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (ice[ny][nx] < 0 && g[ny][nx] == 'X')
      group(ny, nx, c);
  }
}

void dfs(int y, int x, int d, int py, int px) {
  if (g[y][x] == '#' || g[y][x] == 'v')
    return;
  if (ans <= d + abs(y - gy) + abs(x - gx))
    return;
  if (g[y][x] == 'G') {
    ans = d;
    return;
  }

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (py == ny && px == nx)
      continue;
    if (g[ny][nx] == 'v')
      return;
  }

  char cur = g[y][x];
  g[y][x] = 'v';

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    // if(g[ny][nx] == 'v' || g[ny][nx] == '#')continue;
    if (g[ny][nx] == 'X') {
      int curg = ice[ny][nx];
      if (num[curg] > 0) {
        num[curg]--;
        dfs(ny, nx, d + 1, y, x);
        num[curg]++;
      }
    } else {
      dfs(ny, nx, d + 1, y, x);
    }
  }
  g[y][x] = cur;
  return;
}

int main() {
  ios_base::sync_with_stdio(false);
  while (cin >> w >> h) {
    if (w == 0 && h == 0)
      break;
    rep(i, h) rep(j, w) cin >> g[i][j];

    n = 0;
    memset(ice, -1, sizeof(ice));

    rep(i, h) rep(j, w) {
      if (ice[i][j] < 0 && g[i][j] == 'X') {
        num[n] = 0;
        group(i, j, n);
        num[n] /= 2;
        n++;
      }
      if (g[i][j] == 'S') {
        sy = i;
        sx = j;
        g[i][j] = '.';
      }
      if (g[i][j] == 'G') {
        gy = i;
        gx = j;
      }
    }

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

Error: TLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;
typedef pair<int, int> P;

int w, h, sy, sx, gy, gx;
char g[20][20];
int ice[20][20], num[10000], n;
int dis[20][20], ans;
const int dy[] = {-1, 0, 1, 0}, dx[] = {0, 1, 0, -1};
const int INF = 1000000;

void group(int y, int x, int c) {
  num[c]++;
  ice[y][x] = c;

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (ice[ny][nx] < 0 && g[ny][nx] == 'X')
      group(ny, nx, c);
  }
}

void dfs(int y, int x, int d, int py, int px) {
  if (g[y][x] == '#' || g[y][x] == 'v')
    return;
  if (ans <= d + abs(y - gy) + abs(x - gx))
    return;
  if (g[y][x] == 'G') {
    ans = d;
    return;
  }

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    if (py == ny && px == nx)
      continue;
    if (g[ny][nx] == 'v')
      return;
  }

  char cur = g[y][x];
  g[y][x] = 'v';

  rep(i, 4) {
    int ny = y + dy[i], nx = x + dx[i];
    if (ny < 0 || nx < 0 || ny >= h || nx >= w)
      continue;
    // if(g[ny][nx] == 'v' || g[ny][nx] == '#')continue;
    if (g[ny][nx] == 'X') {
      int curg = ice[ny][nx];
      if (num[curg] > 0) {
        num[curg]--;
        dfs(ny, nx, d + 1, y, x);
        num[curg]++;
      }
    } else {
      dfs(ny, nx, d + 1, y, x);
    }
  }
  g[y][x] = cur;
  return;
}

int main() {
  ios_base::sync_with_stdio(false);
  while (cin >> w >> h) {
    if (w == 0 && h == 0)
      break;
    rep(i, h) rep(j, w) cin >> g[i][j];

    n = 0;
    memset(ice, -1, sizeof(ice));

    rep(i, h) rep(j, w) {
      if (ice[i][j] < 0 && g[i][j] == 'X') {
        num[n] = 0;
        group(i, j, n);
        num[n] /= 2;
        n++;
      }
      if (g[i][j] == 'S') {
        sy = i;
        sx = j;
        g[i][j] = '.';
      }
      if (g[i][j] == 'G') {
        gy = i;
        gx = j;
      }
    }

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