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

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using namespace std;

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

const int limit = 1 << 24;
using S = short int;

S pre[3][limit];
S dist[limit];

inline int hstar(int n, int cmask, int tmask) {
  int ret = 0;
  rep(i, n) {
    int cur = (cmask >> (8 * i)) & 255;
    chmax<int>(ret, pre[i][cur]);
  }
  return ret;
}

int main(void) {
  int w, h, n;

  while (cin >> w >> h >> n, n) {
    int smask = 0, tmask = 0;
    string board[16];

    cin.ignore();
    rep(i, h) getline(cin, board[i]);

    // cout << w << " " << h << " " << n << endl;
    // rep(i,h) cout << board[i] << endl;

    rep(i, h) rep(j, w) rep(k, 3) {
      if (board[i][j] == ('a' + k))
        smask |= ((16 * i + j) << (8 * k));
      if (board[i][j] == ('A' + k))
        tmask |= ((16 * i + j) << (8 * k));
    }

    rep(i, 3) {
      fill(pre[i], pre[i] + 256, 300);
      const int start = (tmask >> (8 * i)) & 255;
      pre[i][start] = 0;
      queue<int> q;
      q.push(start);
      while (!q.empty()) {
        int cmask = q.front();
        q.pop();
        const int cy = cmask / 16, cx = cmask % 16;
        rep(j, 4) {
          const int ny = cy + dy[j], nx = cx + dx[j];
          if (board[ny][nx] == '#')
            continue;
          if (chmin<S>(pre[i][16 * ny + nx], pre[i][16 * cy + cx] + 1))
            q.push(16 * ny + nx);
        }
      }
    }

    fill(dist, dist + limit, 30000);
    dist[smask] = 0;
    using state = tuple<S, int>;
    priority_queue<state, vector<state>, greater<state>> q;
    q.push(state(0, smask));

    while (!q.empty()) {
      int cost, cmask;
      tie(cost, cmask) = q.top();
      q.pop();

      if (dist[tmask] != 30000)
        break;

      int cy[3], cx[3], tmp = cmask;
      rep(i, n) {
        cx[i] = tmp & 15;
        tmp >>= 4;
        cy[i] = tmp & 15;
        tmp >>= 4;
      }

      const int all = pow<int>(5, n);

      rep(mask, all) {
        const int didx[3] = {mask % 5, mask / 5 % 5, mask / 25};
        int ny[3], nx[3];
        rep(i, n) {
          ny[i] = cy[i] + dy[didx[i]];
          nx[i] = cx[i] + dx[didx[i]];
        }

        bool ok = true;
        rep(i, n) if (board[ny[i]][nx[i]] == '#') ok = false;
        if (ok == false)
          continue;
        rep(i, n) rep(j, i) if (ny[i] == ny[j] && nx[i] == nx[j]) ok = false;
        if (ok == false)
          continue;
        rep(i, n) rep(j, i) if (ny[i] == cy[j] && nx[i] == cx[j] &&
                                ny[j] == cy[i] && nx[j] == cx[i]) ok = false;
        if (ok == false)
          continue;

        int nmask = 0;
        rep(i, n) nmask |= (16 * ny[i] + nx[i]) << (8 * i);

        if (chmin<S>(dist[nmask], dist[cmask] + 1))
          q.push(state(dist[nmask] + hstar(n, nmask, tmask), nmask));
      }
    }
    cout << dist[tmask] << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using namespace std;

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

const int limit = 1 << 24;
using S = short int;
S dist[limit];

inline int hstar(int n, int cmask, int tmask) {
  int cy[3], cx[3], ty[3], tx[3];
  int ret = 0;
  rep(i, n) {
    cx[i] = cmask & 15;
    cmask >>= 4;
    cy[i] = cmask & 15;
    cmask >>= 4;

    tx[i] = tmask & 15;
    tmask >>= 4;
    ty[i] = tmask & 15;
    tmask >>= 4;

    chmax(ret, abs(cy[i] - ty[i]) + abs(cx[i] - tx[i]));
  }
  return ret;
}

int main(void) {
  int w, h, n;

  while (cin >> w >> h >> n, n) {
    int smask = 0, tmask = 0;
    string board[16];

    cin.ignore();
    rep(i, h) getline(cin, board[i]);

    // cout << w << " " << h << " " << n << endl;
    // rep(i,h) cout << board[i] << endl;

    rep(i, h) rep(j, w) rep(k, 3) {
      if (board[i][j] == ('a' + k))
        smask |= ((16 * i + j) << (8 * k));
      if (board[i][j] == ('A' + k))
        tmask |= ((16 * i + j) << (8 * k));
    }

    fill(dist, dist + limit, 30000);
    dist[smask] = 0;
    using state = tuple<S, int>;
    priority_queue<state, vector<state>, greater<state>> q;
    q.push(state(0, smask));

    while (!q.empty()) {
      int cost, cmask;
      tie(cost, cmask) = q.top();
      q.pop();

      if (dist[tmask] != 30000)
        break;

      int cy[3], cx[3], tmp = cmask;
      rep(i, n) {
        cx[i] = tmp & 15;
        tmp >>= 4;
        cy[i] = tmp & 15;
        tmp >>= 4;
      }

      const int all = pow<int>(5, n);

      rep(mask, all) {
        const int didx[3] = {mask % 5, mask / 5 % 5, mask / 25};
        int ny[3], nx[3];
        rep(i, n) {
          ny[i] = cy[i] + dy[didx[i]];
          nx[i] = cx[i] + dx[didx[i]];
        }

        bool ok = true;
        rep(i, n) if (board[ny[i]][nx[i]] == '#') ok = false;
        if (ok == false)
          continue;
        rep(i, n) rep(j, i) if (ny[i] == ny[j] && nx[i] == nx[j]) ok = false;
        if (ok == false)
          continue;

        rep(i, n) rep(j, i) if (ny[i] == cy[j] && nx[i] == cx[j] &&
                                ny[j] == cy[i] && nx[j] == cx[i]) ok = false;
        if (ok == false)
          continue;

        int nmask = 0;
        rep(i, n) nmask |= (16 * ny[i] + nx[i]) << (8 * i);

        if (chmin<S>(dist[nmask], dist[cmask] + 1))
          q.push(state(dist[nmask] + hstar(n, nmask, tmask), nmask));
      }
    }
    cout << dist[tmask] << endl;
  }
  return 0;
}