Problem p00860 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

typedef vector<pair<int, int>> T;

const int vy[] = {0, 1, 0, -1, 0}, vx[] = {1, 0, -1, 0, 0};

int tail;
vector<pair<int, int>> vec[1000];

int W, H, N;
string S[16];
int v[16 * 16 * 16 * 16 * 16 * 16];

bool isover(int y, int x) {
  return (y < 0 || y >= H || x < 0 || x >= W || S[y][x] == '#');
}

void CreateVector(int sz, vector<pair<int, int>> &vs) {
  if (sz == 0) {
    vec[tail++] = vs;
    return;
  }
  for (int i = 0; i < 5; i++) {
    int ny = vs[sz - 1].first + vy[i];
    int nx = vs[sz - 1].second + vx[i];
    if (isover(ny, nx))
      continue;
    vs[sz - 1].first += vy[i];
    vs[sz - 1].second += vx[i];
    CreateVector(sz - 1, vs);
    vs[sz - 1].first -= vy[i];
    vs[sz - 1].second -= vx[i];
  }
}

int hashh(vector<pair<int, int>> &vs) {
  int ret = 0;
  for (int k = vs.size() - 1; k >= 0; k--) {
    ret *= 16;
    ret += vs[k].second;
    ret *= 16;
    ret += vs[k].first;
  }
  return (ret);
}

vector<pair<int, int>> hashd(int h) {
  vector<pair<int, int>> vs(N);
  int ret = 0;
  for (auto &k : vs) {
    vs[ret].first = h & 15;
    h >>= 4;
    vs[ret++].second = h & 15;
    h >>= 4;
  }
  return (vs);
}

int main() {
  while (cin >> W >> H >> N, W) {
    vector<char> nums;
    cin.ignore();

    for (int i = 0; i < H; i++) {
      getline(cin, S[i]);
      for (int j = 0; j < W; j++) {
        if (islower(S[i][j]))
          nums.push_back(S[i][j]);
      }
    }

    sort(begin(nums), end(nums));

    vector<pair<int, int>> vs(N), ans(N);
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (islower(S[i][j])) {
          auto q = lower_bound(begin(nums), end(nums), S[i][j]) - begin(nums);
          vs[q] = {i, j};
        } else if (isupper(S[i][j])) {
          auto q = lower_bound(begin(nums), end(nums), tolower(S[i][j])) -
                   begin(nums);
          ans[q] = {i, j};
        }
      }
    }

    queue<int> que;
    que.emplace(hashh(vs));
    memset(v, -1, sizeof(v));
    v[hashh(vs)] = 0;

    while (!que.empty()) {
      auto ss = que.front();
      int cost = v[ss];
      que.pop();
      auto p = hashd(ss);
      if (p == ans) {
        cout << cost << endl;
        break;
      }

      tail = 0;
      CreateVector(N, p);
      for (int z = 0; z < tail; z++) {
        auto &beet = vec[z];
        bool isok = true;
        for (int i = 0; i < p.size(); i++) {
          for (int j = 0; j < i; j++) {
            isok &= beet[i] != p[j] || beet[j] != p[i];
            isok &= beet[i] != beet[j];
          }
          if (!isok)
            break;
        }
        int hashed = hashh(beet);
        if (isok && v[hashed] == -1) {
          que.emplace(hashed);
          v[hashed] = cost + 1;
        }
      }
    }
  }
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

typedef vector<pair<int, int>> T;

const int vy[] = {0, 1, 0, -1, 0}, vx[] = {1, 0, -1, 0, 0};

int tail;
vector<pair<int, int>> vec[1000];

int W, H, N;
string S[16];
short v[16 * 16 * 16 * 16 * 16 * 16];

bool isover(int y, int x) {
  return (y < 0 || y >= H || x < 0 || x >= W || S[y][x] == '#');
}

void CreateVector(int sz, vector<pair<int, int>> &vs) {
  if (sz == 0) {
    vec[tail++] = vs;
    return;
  }
  for (int i = 0; i < 5; i++) {
    int ny = vs[sz - 1].first + vy[i];
    int nx = vs[sz - 1].second + vx[i];
    if (isover(ny, nx))
      continue;
    vs[sz - 1].first += vy[i];
    vs[sz - 1].second += vx[i];
    CreateVector(sz - 1, vs);
    vs[sz - 1].first -= vy[i];
    vs[sz - 1].second -= vx[i];
  }
}

int hashh(vector<pair<int, int>> &vs) {
  int ret = 0;
  for (int k = vs.size() - 1; k >= 0; k--) {
    ret *= 16;
    ret += vs[k].second;
    ret *= 16;
    ret += vs[k].first;
  }
  return (ret);
}

vector<pair<int, int>> hashd(int h) {
  vector<pair<int, int>> vs(N);
  int ret = 0;
  for (auto &k : vs) {
    vs[ret].first = h & 15;
    h >>= 4;
    vs[ret++].second = h & 15;
    h >>= 4;
  }
  return (vs);
}

int main() {
  while (cin >> W >> H >> N, W) {
    vector<char> nums;
    cin.ignore();

    for (int i = 0; i < H; i++) {
      getline(cin, S[i]);
      for (int j = 0; j < W; j++) {
        if (islower(S[i][j]))
          nums.push_back(S[i][j]);
      }
    }

    sort(begin(nums), end(nums));

    vector<pair<int, int>> vs(N), ans(N);
    for (int i = 0; i < H; i++) {
      for (int j = 0; j < W; j++) {
        if (islower(S[i][j])) {
          auto q = lower_bound(begin(nums), end(nums), S[i][j]) - begin(nums);
          vs[q] = {i, j};
        } else if (isupper(S[i][j])) {
          auto q = lower_bound(begin(nums), end(nums), tolower(S[i][j])) -
                   begin(nums);
          ans[q] = {i, j};
        }
      }
    }

    queue<int> que;
    que.emplace(hashh(vs));
    memset(v, -1, sizeof(v));
    v[hashh(vs)] = 0;

    while (!que.empty()) {
      auto ss = que.front();
      int cost = v[ss];
      que.pop();
      auto p = hashd(ss);
      if (p == ans) {
        cout << cost << endl;
        break;
      }

      tail = 0;
      CreateVector(N, p);
      for (int z = 0; z < tail; z++) {
        auto &beet = vec[z];
        bool isok = true;
        for (int i = 0; i < p.size(); i++) {
          for (int j = 0; j < i; j++) {
            isok &= beet[i] != p[j] || beet[j] != p[i];
            isok &= beet[i] != beet[j];
          }
          if (!isok)
            break;
        }
        int hashed = hashh(beet);
        if (isok && v[hashed] == -1) {
          que.emplace(hashed);
          v[hashed] = cost + 1;
        }
      }
    }
  }
}