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

#include <iostream>
#include <map>
#include <queue>

using namespace std;

typedef pair<int, int> P;

int Move(int, int, int);
int Get(int, int);
void Set(int &, int, int);

int main() {
  const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
  map<int, int> memo;
  queue<P> que;
  que.push(P(01234567, 0));
  while (!que.empty()) {
    int p = que.front().first;
    int t = que.front().second;
    que.pop();
    if (memo.find(p) != memo.end()) {
      continue;
    }
    memo[p] = t;
    for (int i = 0; i < 4; ++i) {
      int np = Move(p, dx[i], dy[i]);
      if (np == -1) {
        continue;
      }
      que.push(P(np, t + 1));
    }
  }

  while (1) {
    int p = 0;
    for (int i = 0; i < 8; ++i) {
      int a;
      if (!(cin >> a)) {
        return 0;
      }
      Set(p, i, a);
    }
    cout << memo[p] << endl;
  }
  return 0;
}

int Move(int p, int dx, int dy) {
  int res = p;
  int zx, zy, zp;
  for (int i = 0; i < 8; ++i) {
    int a = Get(res, i);
    if (!a) {
      zx = i % 4;
      zy = i / 4;
      zp = i;
      break;
    }
  }
  int nzx = zx + dx, nzy = zy + dy, nzp = nzy * 4 + nzx;
  if (nzx < 0 || nzx >= 4 || nzy < 0 || nzy >= 2) {
    return -1;
  }

  int num1 = Get(res, zp), num2 = Get(res, nzp);
  Set(res, nzp, num1);
  Set(res, zp, num2);

  return res;
}

int Get(int p, int n) {
  int shift = 3 * (7 - n);
  return ((p & (7 << shift)) >> shift);
}

void Set(int &p, int n, int a) {
  int shift = 3 * (7 - n);
  p &= ~(7 << shift);
  p |= (a << shift);
}

Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <set>
using namespace std;

typedef pair<int, int> P;

#define CLEAR 01234567

int Move(int, int, int);
int Get(int, int);
void Set(int &, int, int);

int main() {
  const int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
  while (1) {
    if (cin.eof()) {
      break;
    }
    int fp = 0;
    for (int i = 0; i < 8; ++i) {
      int a;
      cin >> a;
      Set(fp, i, a);
    }

    int ans;
    queue<P> que;
    set<int> IDset;
    que.push(P(fp, 0));

    while (!que.empty()) {
      int p = que.front().first;
      int t = que.front().second;
      que.pop();
      if (p == CLEAR) {
        ans = t;
        break;
      }
      if (IDset.find(p) != IDset.end()) {
        continue;
      }
      IDset.insert(p);
      for (int i = 0; i < 4; ++i) {
        int np = Move(p, dx[i], dy[i]);
        if (np == -1) {
          continue;
        }
        que.push(P(np, t + 1));
      }
    }
    cout << ans << endl;
  }
}

int Move(int p, int dx, int dy) {
  int res = p;
  int zx, zy, zp;
  for (int i = 0; i < 8; ++i) {
    int a = Get(res, i);
    if (!a) {
      zx = i % 4;
      zy = i / 4;
      zp = i;
      break;
    }
  }
  int nzx = zx + dx, nzy = zy + dy, nzp = nzy * 4 + nzx;
  if (nzx < 0 || nzx >= 4 || nzy < 0 || nzy >= 2) {
    return -1;
  }

  int num1 = Get(res, zp), num2 = Get(res, nzp);
  Set(res, nzp, num1);
  Set(res, zp, num2);

  return res;
}

// n番目を取り出す
int Get(int p, int n) {
  int shift = 3 * (7 - n);
  return ((p & (7 << shift)) >> shift);
}

// n番目をaにする
void Set(int &p, int n, int a) {
  int shift = 3 * (7 - n);
  p &= ~(7 << shift);
  p |= (a << shift);
}