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

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

int val[8];
int dp[16777217];

class State {
public:
  int t, cost;

  State(int tt, int tcost) {
    t = tt;
    cost = tcost;
  }
};

int change(int t, int from, int to) {
  int digit = (t / val[to]) % val[1];
  return t - digit * val[to] + digit * val[from];
}

int zeroIdx(int t) {
  for (int i = 0; i < 8; i++) {
    if ((t / val[i]) % val[1] == 0)
      return i;
  }
  return -1;
}

int DP(void) {
  int start = 0;
  for (int i = 0; i < 8; i++) {
    val[i] = (int)pow(8, i);
    start += i * val[i];
  }

  queue<State> open;
  State st(start, 0);
  open.push(st);
  dp[start] = -1;

  while (!open.empty()) {
    st = open.front();
    open.pop();
    int idx = zeroIdx(st.t);

    if (idx >= 4) {
      int aft = change(st.t, idx, idx - 4);
      if (dp[aft] == 0) {
        dp[aft] = st.cost + 1;
        open.push(State(aft, st.cost + 1));
      }
    } else if (idx < 4) {
      int aft = change(st.t, idx, idx + 4);
      if (dp[aft] == 0) {
        dp[aft] = st.cost + 1;
        open.push(State(aft, st.cost + 1));
      }
    }
    if (idx % 4 > 0) {
      int aft = change(st.t, idx, idx - 1);
      if (dp[aft] == 0) {
        dp[aft] = st.cost + 1;
        open.push(State(aft, st.cost + 1));
      }
    }
    if (idx % 4 < 3) {
      int aft = change(st.t, idx, idx + 1);
      if (dp[aft] == 0) {
        dp[aft] = st.cost + 1;
        open.push(State(aft, st.cost + 1));
      }
    }
  }

  dp[start] = 0;
}

int main(void) {
  DP();

  while (1) {
    int sum = 0;
    for (int i = 0; i < 8; i++) {
      int x;
      if (!(cin >> x))
        return 0;
      sum += x * val[i];
    }
    cout << dp[sum] << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

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

class Info {
public:
  vector<int> v;
  int depth;
};

bool is_ans(vector<int> v) {
  for (int i = 0; i < 8; i++) {
    if (v[i] != i) {
      return false;
    }
  }
  return true;
}

vector<int> slide_piece(vector<int> v, int dir) {
  int from, to;

  for (from = 0; v[from] != 0; from++)
    ;

  if (dir == 0) {
    to = from - 4;
    if (to >= 0) {
      swap(v[from], v[to]);
    }
  } else if (dir == 1) {
    to = from + 1;
    if (to < 8 && from / 4 == to / 4) {
      swap(v[from], v[to]);
    }
  } else if (dir == 2) {
    to = from + 4;
    if (to < 8) {
      swap(v[from], v[to]);
    }
  } else {
    to = from - 1;
    if (to >= 0 && from / 4 == to / 4) {
      swap(v[from], v[to]);
    }
  }

  return v;
}

int bfs(vector<int> v) {
  if (is_ans(v)) {
    return 0;
  }

  set<vector<int>> s;
  queue<Info> q;
  vector<int> next_v;

  Info next_info, now_info = {v, 0};
  q.push(now_info);
  s.insert(v);

  while (!q.empty()) {
    now_info = q.front();
    q.pop();

    for (int i = 0; i < 4; i++) {
      next_v = slide_piece(now_info.v, i);

      if (now_info.v != next_v && s.find(next_v) == s.end()) {
        if (is_ans(next_v)) {
          return now_info.depth + 1;
        }

        next_info.v = next_v;
        next_info.depth = now_info.depth + 1;
        q.push(next_info);
        s.insert(next_v);
      }
    }
  }
}

int main(void) {
  int i;
  vector<int> v(8);

  while (1) {
    for (i = 0; i < 8; i++) {
      if (!(cin >> v[i]))
        return 0;
    }
    cout << bfs(v) << endl;
  }
}