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

#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <utility>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)

typedef pair<int, int> Ps;
set<pair<Ps, int>> memo;
char f[17][17];

class State {
public:
  vector<Ps> b;
  Ps p;
  int c;
  State(Ps p, int c, vector<Ps> &b) : p(p), c(c), b(b) {}
};

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};

int main() {
  int W, H;
  while (cin >> W >> H, (W || H)) {
    memo.clear();

    Ps init;
    vector<Ps> bk;
    REP(i, H) REP(j, W) {
      cin >> f[j][i];
      if (f[j][i] == '@')
        init = make_pair(j, i);
      if (f[j][i] == '*')
        bk.push_back(make_pair(j, i));
    }

    queue<State> q;
    q.push(State(init, 0, bk));

    while (!q.empty()) {
      State s = q.front();
      q.pop();
      bool ed = true;
      REP(i, s.b.size()) {
        Ps p = s.b[i];
        if (f[p.first][p.second] != '_')
          ed = false;
      }

      if (ed) {
        cout << s.c << endl;
        break;
      }

      REP(i, 4) {
        Ps p = s.p;
        int tx = p.first + dx[i], ty = p.second + dy[i];
        if (tx < 0 || ty < 0 || tx >= W || ty >= H)
          continue;
        if (f[tx][ty] == '#')
          continue;

        bool g = true;
        vector<Ps> tmp(3);
        REP(j, s.b.size()) {
          Ps bp = s.b[j];
          if (bp.first == tx && bp.second == ty) {
            int ttx = bp.first + dx[i], tty = bp.second + dy[i];
            if (ttx < 0 || tty < 0 || ttx >= W || tty >= H) {
              g = false;
              break;
            }
            if (f[ttx][tty] == '#') {
              g = false;
              break;
            }
            REP(k, s.b.size()) {
              if (k == j)
                continue;
              if (s.b[k] == make_pair(ttx, tty)) {
                g = false;
                break;
              }
            }

            if (g)
              tmp[j] = make_pair(ttx, tty);
            else
              break;
          } else
            tmp[j] = bp;
        }

        if (!g)
          continue;

        sort(tmp.begin(), tmp.end());
        int th = 0;
        REP(k, tmp.size()) {
          th <<= 4;
          th |= (tmp[k].first - 1);
          th <<= 4;
          th |= (tmp[k].second - 1);
        }
        Ps np = make_pair(tx, ty);
        if (memo.count(make_pair(np, th)))
          continue;

        memo.insert(make_pair(np, th));

        q.push(State(np, s.c + 1, tmp));
      }
    }
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>
#include <queue>
#include <set>
#include <utility>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < n; i++)

typedef pair<int, int> Ps;
set<pair<Ps, vector<Ps>>> memo;

class State {
public:
  vector<Ps> b;
  Ps p;
  int c;
  State(Ps p, int c, vector<Ps> &b) : p(p), c(c), b(b) {}
};

int dx[] = {-1, 0, 1, 0};
int dy[] = {0, -1, 0, 1};

int main() {
  int W, H;
  while (cin >> W >> H, (W || H)) {
    memo.clear();

    char f[17][17];
    Ps init;
    vector<Ps> bk;
    REP(i, H) REP(j, W) {
      cin >> f[j][i];
      if (f[j][i] == '@')
        init = make_pair(j, i);
      if (f[j][i] == '*')
        bk.push_back(make_pair(j, i));
    }

    queue<State> q;
    q.push(State(init, 0, bk));

    while (!q.empty()) {
      State s = q.front();
      q.pop();
      bool ed = true;
      REP(i, s.b.size()) {
        Ps p = s.b[i];
        if (f[p.first][p.second] != '_')
          ed = false;
      }

      if (ed) {
        cout << s.c << endl;
        break;
      }

      REP(i, 4) {
        Ps p = s.p;
        int tx = p.first + dx[i], ty = p.second + dy[i];
        if (tx < 0 || ty < 0 || tx >= W || ty >= H)
          continue;
        if (f[tx][ty] == '#')
          continue;

        bool g = true;
        vector<Ps> tmp;
        REP(j, s.b.size()) {
          Ps bp = s.b[j];
          if (bp.first == tx && bp.second == ty) {
            int ttx = bp.first + dx[i], tty = bp.second + dy[i];
            if (ttx < 0 || tty < 0 || ttx >= W || tty >= H) {
              g = false;
              break;
            }
            if (f[ttx][tty] == '#') {
              g = false;
              break;
            }
            REP(k, s.b.size()) {
              if (k == j)
                continue;
              if (s.b[k] == make_pair(ttx, tty)) {
                g = false;
                break;
              }
            }

            if (g)
              tmp.push_back(make_pair(ttx, tty));
          } else
            tmp.push_back(bp);
        }

        if (!g)
          continue;

        sort(tmp.begin(), tmp.end());
        Ps np = make_pair(tx, ty);
        if (memo.count(make_pair(np, tmp)))
          continue;
        memo.insert(make_pair(np, tmp));

        q.push(State(np, s.c + 1, tmp));
      }
    }
  }
}