Problem p00711 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <iostream>
using namespace std;

const int NUM = 7;

void grooping(int y, int x, int w, int h, char **room, unsigned long ***group,
              unsigned long *next) {
  if (room[y][x] != '#') {
    for (int i = y - 1; i <= y + 1; i++) {
      for (int j = x - 1; j <= x + 1; j++) {
        if (i < 0 || j < 0 || i >= h || j >= w) {
          continue;
        }
        if ((i == y && j != x) || (i != y && j == x)) {
          for (int k = 0; k < NUM; k++) {
            group[y][x][k] |= group[i][j][k];
          }
        }
      }
    }
    for (int i = 0; i < NUM; i++) {
      if (group[y][x][i] == 0UL && next[i] != 0UL) {
        group[y][x][i] |= next[i];
        next[i] <<= 1;
        break;
      }
    }
  }
}

int main() {
  int w, h;
  while (true) {
    cin >> w >> h;
    if (w == 0 && h == 0) {
      break;
    }

    unsigned long next[NUM] = {1UL, 1UL, 1UL, 1UL, 1UL, 1UL, 1UL};
    char **room = new char *[h];
    unsigned long ***group = new unsigned long **[h];
    int x, y;
    for (int i = 0; i < h; i++) {
      room[i] = new char[w];
      group[i] = new unsigned long *[w];
      for (int j = 0; j < w; j++) {
        cin >> room[i][j];
        if (room[i][j] == '@') {
          x = j;
          y = i;
        }
        group[i][j] = new unsigned long[NUM];
        for (int k = 0; k < NUM; k++) {
          group[i][j][k] = 0UL;
        }
      }
    }

    for (int k = 0; k < 210; k++) {
      for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
          grooping(i, j, w, h, room, group, next);
        }
      }
      for (int i = h - 1; i >= 0; i--) {
        for (int j = w - 1; j >= 0; j--) {
          grooping(i, j, w, h, room, group, next);
        }
      }
      for (int j = 0; j < w; j++) {
        for (int i = 0; i < h; i++) {
          grooping(i, j, w, h, room, group, next);
        }
      }
      for (int j = w - 1; j >= 0; j--) {
        for (int i = h - 1; i >= 0; i--) {
          grooping(i, j, w, h, room, group, next);
        }
      }
    }

    int count = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (int k = 0; k < NUM; k++) {
          if ((group[i][j][k] & group[y][x][k]) != 0UL) {
            count++;
            break;
          }
        }
      }
    }

    cout << count << '\n';

    for (int i = 0; i < h; i++) {
      delete[] room[i];
      for (int j = 0; j < w; j++) {
        delete[] group[i][j];
      }
      delete[] group[i];
    }
    delete[] room;
    delete[] group;
  }

  return 0;
}

Fixed submission:
#include <iostream>
using namespace std;

const int NUM = 7;

void grooping(int y, int x, int w, int h, char **room, unsigned long ***group,
              unsigned long *next) {
  if (room[y][x] != '#') {
    for (int i = y - 1; i <= y + 1; i++) {
      for (int j = x - 1; j <= x + 1; j++) {
        if (i < 0 || j < 0 || i >= h || j >= w) {
          continue;
        }
        if ((i == y && j != x) || (i != y && j == x)) {
          for (int k = 0; k < NUM; k++) {
            group[y][x][k] |= group[i][j][k];
          }
        }
      }
    }
    for (int i = 0; i < NUM; i++) {
      if (group[y][x][i] == 0UL && next[i] != 0UL) {
        group[y][x][i] |= next[i];
        next[i] <<= 1;
        break;
      }
    }
  }
}

int main() {
  int w, h;
  while (true) {
    cin >> w >> h;
    if (w == 0 && h == 0) {
      break;
    }

    unsigned long next[NUM] = {1UL, 1UL, 1UL, 1UL, 1UL, 1UL, 1UL};
    char **room = new char *[h];
    unsigned long ***group = new unsigned long **[h];
    int x, y;
    for (int i = 0; i < h; i++) {
      room[i] = new char[w];
      group[i] = new unsigned long *[w];
      for (int j = 0; j < w; j++) {
        cin >> room[i][j];
        if (room[i][j] == '@') {
          x = j;
          y = i;
        }
        group[i][j] = new unsigned long[NUM];
        for (int k = 0; k < NUM; k++) {
          group[i][j][k] = 0UL;
        }
      }
    }

    for (int k = 0; k < 180; k++) {
      for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
          grooping(i, j, w, h, room, group, next);
        }
      }
      for (int i = h - 1; i >= 0; i--) {
        for (int j = w - 1; j >= 0; j--) {
          grooping(i, j, w, h, room, group, next);
        }
      }
      for (int j = 0; j < w; j++) {
        for (int i = 0; i < h; i++) {
          grooping(i, j, w, h, room, group, next);
        }
      }
      for (int j = w - 1; j >= 0; j--) {
        for (int i = h - 1; i >= 0; i--) {
          grooping(i, j, w, h, room, group, next);
        }
      }
    }

    int count = 0;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        for (int k = 0; k < NUM; k++) {
          if ((group[i][j][k] & group[y][x][k]) != 0UL) {
            count++;
            break;
          }
        }
      }
    }

    cout << count << '\n';

    for (int i = 0; i < h; i++) {
      delete[] room[i];
      for (int j = 0; j < w; j++) {
        delete[] group[i][j];
      }
      delete[] group[i];
    }
    delete[] room;
    delete[] group;
  }

  return 0;
}