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

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

int h, w, n;
vector<string> grid;

class Data {
public:
  vector<int> p;
  bitset<3> bs;
  Data(vector<int> &p0, bitset<3> bs0) {
    p = p0;
    bs = bs0;
  }
  int toInt() {
    int ret = bs.to_ulong();
    for (int i = 0; i < n; ++i) {
      ret *= h * w;
      ret += p[i];
    }
    return ret;
  }
};

int solve() {
  string gridLine = accumulate(grid.begin(), grid.end(), string());
  int diff[] = {1, -1, w, -w};

  vector<int> sp(n), gp(n);
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      int c = grid[i][j];
      if ('a' <= c && c <= 'c') {
        sp[c - 'a'] = i * w + j;
      } else if ('A' <= c && c <= 'C') {
        gp[c - 'A'] = i * w + j;
      }
    }
  }

  int size = 1 << n;
  for (int i = 0; i < n; ++i)
    size *= h * w;

  vector<vector<bool>> check(2, vector<bool>(size, false));
  check[0][Data(sp, 0).toInt()] = true;
  check[1][Data(gp, 0).toInt()] = true;
  vector<deque<Data>> dq(2);
  dq[0].push_back(Data(sp, 0));
  dq[1].push_back(Data(gp, 0));

  int turn = 0;
  int m = 1;
  int ret = 1;
  for (;;) {
    if (m == 0) {
      ++ret;
      turn ^= 1;
      m = dq[turn].size();
    }

    Data d = dq[turn].front();
    dq[turn].pop_front();
    --m;

    for (int i = 0; i < n; ++i) {
      if (d.bs[i])
        continue;
      d.bs[i] = true;
      for (int j = 0; j < 4; ++j) {
        d.p[i] += diff[j];

        bool ok = true;
        if (gridLine[d.p[i]] == '#')
          ok = false;
        for (int k = 0; k < n; ++k) {
          if (k != i && d.p[k] == d.p[i])
            ok = false;
        }

        if (ok) {
          int a = d.toInt();
          if (!check[turn][a]) {
            dq[turn].push_front(d);
            ++m;
            check[turn][a] = true;
          }
        }

        d.p[i] -= diff[j];
      }
      d.bs[i] = false;
    }

    d.bs = 0;
    int a = d.toInt();
    if (!check[turn][a]) {
      if (check[turn ^ 1][a])
        return ret;
      dq[turn].push_back(d);
      check[turn][a] = true;
    }
  }
}

int main() {
  for (;;) {
    cin >> w >> h >> n;
    if (w == 0)
      return 0;
    cin.ignore();

    grid.resize(h);
    for (int i = 0; i < h; ++i)
      getline(cin, grid[i]);

    cout << solve() << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cfloat>
#include <climits>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
using namespace std;

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

int h, w, n;
vector<string> grid;

class Data {
public:
  vector<int> y, x;
  bitset<3> bs;
  Data(vector<int> &y0, vector<int> &x0, bitset<3> bs0) {
    y = y0;
    x = x0;
    bs = bs0;
  }
  int toInt() {
    int ret = bs.to_ulong();
    for (int i = 0; i < n; ++i) {
      ret *= h - 2;
      ret += y[i] - 1;
      ret *= w - 2;
      ret += x[i] - 1;
    }
    return ret;
  }
};

int solve() {
  vector<int> sy(n), sx(n), gy(n), gx(n);
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      int c = grid[i][j];
      if ('a' <= c && c <= 'c') {
        sy[c - 'a'] = i;
        sx[c - 'a'] = j;
      } else if ('A' <= c && c <= 'C') {
        gy[c - 'A'] = i;
        gx[c - 'A'] = j;
      }
    }
  }

  int size = 1 << n;
  for (int i = 0; i < n; ++i)
    size *= (h - 2) * (w - 2);

  vector<vector<bool>> check(2, vector<bool>(size, false));
  check[0][Data(sy, sx, 0).toInt()] = true;
  check[1][Data(gy, gx, 0).toInt()] = true;
  vector<deque<Data>> dq(2);
  dq[0].push_back(Data(sy, sx, 0));
  dq[1].push_back(Data(gy, gx, 0));

  int turn = 0;
  int m = 1;
  int ret = 1;
  for (;;) {
    if (m == 0) {
      ++ret;
      turn ^= 1;
      m = dq[turn].size();
    }

    Data d = dq[turn].front();
    dq[turn].pop_front();
    --m;

    for (int i = 0; i < n; ++i) {
      if (d.bs[i])
        continue;
      d.bs[i] = true;
      for (int j = 0; j < 4; ++j) {
        d.y[i] += dy[j];
        d.x[i] += dx[j];

        bool ok = true;
        if (grid[d.y[i]][d.x[i]] == '#')
          ok = false;
        for (int k = 0; k < n; ++k) {
          if (k != i && d.y[k] == d.y[i] && d.x[k] == d.x[i])
            ok = false;
        }

        if (ok) {
          int a = d.toInt();
          if (!check[turn][a]) {
            dq[turn].push_front(d);
            ++m;
            check[turn][a] = true;
          }
        }

        d.y[i] -= dy[j];
        d.x[i] -= dx[j];
      }
      d.bs[i] = false;
    }

    d.bs = 0;
    int a = d.toInt();
    if (!check[turn][a]) {
      if (check[turn ^ 1][a])
        return ret;
      dq[turn].push_back(d);
      check[turn][a] = true;
    }
  }
}

int main() {
  for (;;) {
    cin >> w >> h >> n;
    if (w == 0)
      return 0;
    cin.ignore();

    grid.resize(h);
    for (int i = 0; i < h; ++i)
      getline(cin, grid[i]);

    cout << solve() << endl;
  }
}