Problem p00883 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
int n;

bool onmp(int x, int y) { return x >= 0 && y >= 0 && x < n && y < n; }

int count(int x, int y, const vector<string> &A) {
  int res = 0;
  for (int i = -1; i <= 1; i++)
    for (int j = -1; j <= 1; j++) {
      int nx = x + i, ny = y + j;
      if ((!i && !j) || !onmp(nx, ny))
        continue;
      res += A[ny][nx] == '#' || A[ny][nx] == '@';
    }
  return res;
}

bool check(const vector<string> &A) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (A[i][j] == '#')
        return 0;
  return 1;
}

vector<string> mkmp(const vector<string> &A) {
  vector<string> res(n, string(n, '.'));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      int cnt = count(j, i, A);
      if (A[i][j] == '#')
        res[i][j] = (cnt == 2 || cnt == 3) ? '#' : '.';
      if (A[i][j] == '.')
        res[i][j] = (cnt == 3) ? '#' : '.';
      if (A[i][j] == '@')
        res[i][j] = '@';
    }
  return res;
}

map<vector<string>, int> mem;
int ans;
void dfs(int x, int y, int cnt, vector<string> A) {
  if (check(A))
    ans = min(cnt, ans);
  if (cnt >= ans)
    return;
  if (mem.count(A) && mem[A] <= cnt)
    return;
  mem[A] = cnt;
  A[y][x] = '.';
  for (int dy = -1; dy <= 1; dy++) {
    for (int dx = -1; dx <= 1; dx++) {
      int nx = x + dx, ny = y + dy;
      if ((!dx && !dy) || !onmp(nx, ny) || A[ny][nx] == '#')
        continue;
      A[ny][nx] = '@';
      dfs(nx, ny, cnt + 1, mkmp(A));
      A[ny][nx] = '.';
    }
  }
}

int main() {
  while (cin >> n, n) {
    vector<string> mp(n);
    for (int i = 0; i < n; i++)
      cin >> mp[i];
    int sx, sy;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        if (mp[i][j] == '@')
          sy = i, sx = j;
    ans = 11;
    mem.clear();
    dfs(sx, sy, 0, mp);
    cout << (ans < 11 ? ans : -1) << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
int n;

bool onmp(int x, int y) { return x >= 0 && y >= 0 && x < n && y < n; }

int count(int x, int y, const vector<string> &A) {
  int res = 0;
  for (int i = -1; i <= 1; i++)
    for (int j = -1; j <= 1; j++) {
      int nx = x + i, ny = y + j;
      if ((!i && !j) || !onmp(nx, ny))
        continue;
      res += A[ny][nx] == '#' || A[ny][nx] == '@';
    }
  return res;
}

bool check(const vector<string> &A) {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (A[i][j] == '#')
        return 0;
  return 1;
}

vector<string> mkmp(const vector<string> &A) {
  vector<string> res(n, string(n, '.'));
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      int cnt = count(j, i, A);
      if (A[i][j] == '#')
        res[i][j] = (cnt == 2 || cnt == 3) ? '#' : '.';
      if (A[i][j] == '.')
        res[i][j] = (cnt == 3) ? '#' : '.';
      if (A[i][j] == '@')
        res[i][j] = '@';
    }
  return res;
}

map<vector<string>, int> mem;
int ans;
void dfs(int x, int y, int cnt, vector<string> A) {
  if (check(A))
    ans = min(cnt, ans);
  if (cnt >= ans)
    return;
  if (mem.count(A) && mem[A] <= cnt)
    return;
  mem[A] = cnt;
  A[y][x] = '.';
  for (int dy = -1; dy <= 1; dy++) {
    for (int dx = -1; dx <= 1; dx++) {
      int nx = x + dx, ny = y + dy;
      if ((!dx && !dy) || !onmp(nx, ny) || A[ny][nx] == '#')
        continue;
      A[ny][nx] = '@';
      dfs(nx, ny, cnt + 1, mkmp(A));
      A[ny][nx] = '.';
    }
  }
}

int main() {
  while (cin >> n, n) {
    vector<string> mp(n);
    for (int i = 0; i < n; i++)
      cin >> mp[i];
    int sx, sy;
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        if (mp[i][j] == '@')
          sy = i, sx = j;
    ans = 11;
    dfs(sx, sy, 0, mp);
    cout << (ans < 11 ? ans : -1) << endl;
  }
  return 0;
}