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

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

const int dx[] = {0, -1, 0, 1, 0, -1, 1, 1, -1, -2, 0, 2, 0};
const int dy[] = {0, 0, -1, 0, 1, -1, -1, 1, 1, 0, -2, 0, 2};
const int sz[] = {5, 9, 13};

struct Ink {
  int x, y, val;
  Ink(int x = 0, int y = 0, int val = 0) : x(x), y(y), val(val) {}
  bool operator<(const Ink &t) const {
    if (x != t.x)
      return x < t.x;
    if (y != t.y)
      return y < t.y;
    return val < t.val;
  }
};

set<int> done;
int grid[10][10];

inline int hash_(vector<Ink> &c, int n, int nx, int ny) {
  typedef unsigned int uint;
  uint p = 1e9 + 7;
  uint mod = 1e9 + 9;
  uint h = 0;
  for (int i = 0; i < c.size(); i++) {
    h = (h * p + c[i].x) % mod;
    h = (h * p + c[i].y) % mod;
    h = (h * p + c[i].val) % mod;
  }
  h = (h * p + n) % mod;
  h = (h * p + nx) % mod;
  h = (h * p + ny) % mod;
  return h;
}

inline bool ingrid(int x, int y) {
  return x >= 0 && y >= 0 && x < 10 && y < 10;
}

vector<Ink> search(int n, vector<Ink> c, int nx, int ny) {
  if (n == 0) {
    if (c.size() == 0)
      return vector<Ink>(1);
    else
      return vector<Ink>(0);
  }
  if (c.size() == 0)
    return vector<Ink>(0);

  for (int i = 0; i < c.size(); i++) {
    if (nx - 2 > c[i].x)
      return vector<Ink>(0);
    else if (nx - 2 == c[i].x) {
      if (ny > c[i].y)
        return vector<Ink>(0);
    }
  }

  memset(grid, 0, sizeof(grid));
  for (int i = 0; i < c.size(); i++) {
    grid[c[i].x][c[i].y] = c[i].val;
  }

  for (; nx < 10; nx++) {
    for (; ny < 10; ny++) {
      for (int s = 0; s < 3; s++) {
        bool f = true;
        for (int dir = 0; dir < sz[s]; dir++) {
          int tx = nx + dx[dir];
          int ty = ny + dy[dir];
          // if (!ingrid(tx, ty)) continue;
          if (!ingrid(tx, ty) || grid[tx][ty] == 0) {
            for (int dir2 = 0; dir2 < dir; dir2++) {
              int tx2 = nx + dx[dir2];
              int ty2 = ny + dy[dir2];
              grid[tx2][ty2]++;
            }
            f = false;
            break;
          }
          grid[tx][ty]--;
        }
        if (!f)
          continue;
        vector<Ink> v;
        for (int i = 0; i < c.size(); i++) {
          if (grid[c[i].x][c[i].y]) {
            v.push_back(Ink(c[i].x, c[i].y, grid[c[i].x][c[i].y]));
          }
        }
        vector<Ink> t = search(n - 1, v, nx, ny);
        if (t.size()) {
          t.push_back(Ink(nx, ny, s));
          return t;
        }
        for (int dir = 0; dir < sz[s]; dir++) {
          int tx = nx + dx[dir];
          int ty = ny + dy[dir];
          // if (!ingrid(tx, ty)) continue;
          grid[tx][ty]++;
        }
      }
    }
    ny = 0;
  }

  int h = hash_(c, n, nx, ny);
  if (done.count(h))
    return vector<Ink>(0);
  done.insert(h);

  return vector<Ink>(0);
}

int main() {
  int n;
  scanf("%d", &n);
  vector<Ink> c;
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      int x;
      scanf("%d", &x);
      if (x)
        c.push_back(Ink(i, j, x));
    }
  }

  vector<Ink> res = search(n, c, 0, 0);
  for (int i = 1; i < res.size(); i++) {
    printf("%d %d %d\\n", res[i].y, res[i].x, ++res[i].val);
  }
}

Error: MLE

Fixed submission:

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

const int dx[] = {0, -1, 0, 1, 0, -1, 1, 1, -1, -2, 0, 2, 0};
const int dy[] = {0, 0, -1, 0, 1, -1, -1, 1, 1, 0, -2, 0, 2};
const int sz[] = {5, 9, 13};

struct Ink {
  int x, y, val;
  Ink(int x = 0, int y = 0, int val = 0) : x(x), y(y), val(val) {}
  bool operator<(const Ink &t) const {
    if (x != t.x)
      return x < t.x;
    if (y != t.y)
      return y < t.y;
    return val < t.val;
  }
};

set<int> done;
int grid[10][10];

inline int hash_(vector<Ink> &c, int n, int nx, int ny) {
  typedef unsigned int uint;
  uint p = 1e9 + 7;
  uint mod = 1e9 + 9;
  uint h = 0;
  for (int i = 0; i < c.size(); i++) {
    h = (h * p + c[i].x) % mod;
    h = (h * p + c[i].y) % mod;
    h = (h * p + c[i].val) % mod;
  }
  h = (h * p + n) % mod;
  h = (h * p + nx) % mod;
  h = (h * p + ny) % mod;
  return h;
}

inline bool ingrid(int x, int y) {
  return x >= 0 && y >= 0 && x < 10 && y < 10;
}

vector<Ink> search(int n, vector<Ink> c, int nx, int ny) {
  int h = hash_(c, n, nx, ny);
  if (done.count(h))
    return vector<Ink>(0);
  done.insert(h);

  if (n == 0) {
    if (c.size() == 0)
      return vector<Ink>(1);
    else
      return vector<Ink>(0);
  }
  if (c.size() == 0)
    return vector<Ink>(0);

  for (int i = 0; i < c.size(); i++) {
    if (nx - 2 > c[i].x)
      return vector<Ink>(0);
    else if (nx - 2 == c[i].x) {
      if (ny > c[i].y)
        return vector<Ink>(0);
    }
  }

  memset(grid, 0, sizeof(grid));
  for (int i = 0; i < c.size(); i++) {
    grid[c[i].x][c[i].y] = c[i].val;
  }

  for (; nx < 10; nx++) {
    for (; ny < 10; ny++) {
      for (int s = 0; s < 3; s++) {
        bool f = true;
        for (int dir = 0; dir < sz[s]; dir++) {
          int tx = nx + dx[dir];
          int ty = ny + dy[dir];
          // if (!ingrid(tx, ty)) continue;
          if (!ingrid(tx, ty) || grid[tx][ty] == 0) {
            for (int dir2 = 0; dir2 < dir; dir2++) {
              int tx2 = nx + dx[dir2];
              int ty2 = ny + dy[dir2];
              grid[tx2][ty2]++;
            }
            f = false;
            break;
          }
          grid[tx][ty]--;
        }
        if (!f)
          continue;
        vector<Ink> v;
        for (int i = 0; i < c.size(); i++) {
          if (grid[c[i].x][c[i].y]) {
            v.push_back(Ink(c[i].x, c[i].y, grid[c[i].x][c[i].y]));
          }
        }
        vector<Ink> t = search(n - 1, v, nx, ny);
        if (t.size()) {
          t.push_back(Ink(nx, ny, s));
          return t;
        }
        for (int dir = 0; dir < sz[s]; dir++) {
          int tx = nx + dx[dir];
          int ty = ny + dy[dir];
          // if (!ingrid(tx, ty)) continue;
          grid[tx][ty]++;
        }
      }
    }
    ny = 0;
  }

  return vector<Ink>(0);
}

int main() {
  int n;
  scanf("%d", &n);
  vector<Ink> c;
  for (int i = 0; i < 10; i++) {
    for (int j = 0; j < 10; j++) {
      int x;
      scanf("%d", &x);
      if (x)
        c.push_back(Ink(i, j, x));
    }
  }

  vector<Ink> res = search(n, c, 0, 0);
  for (int i = 1; i < res.size(); i++) {
    printf("%d %d %d\\n", res[i].y, res[i].x, ++res[i].val);
  }
}