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

#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <string>

using namespace std;

int const N = 8;
int const pow_10[N] = {10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};
class card {
  static int const Offset = 1;

public:
  template <typename T> card(T const &t) {
    for (int y = 0; y < 2; ++y) {
      for (int x = 0; x < N / 2; ++x) {
        num_[y][x] = t[y * N / 2 + x] + Offset;
        if (num_[y][x] == Offset) {
          x0_ = x;
          y0_ = y;
        }
      }
    }
  }

public:
  card make_moved(int const dir) const {
    card ret(*this);

    switch (dir) {
    case 0:
      ret.to_up();
      break;
    case 1:
      ret.to_right();
      break;
    case 2:
      ret.to_down();
      break;
    case 3:
      ret.to_left();
      break;
    }

    return ret;
  }

public:
  operator long long int() const {
    long long int p = 0;
    static bool pp = false;

    for (int y = 0; y < 2; ++y) {
      for (int x = 0; x < N / 2; ++x) {
        p += num_[y][x] * pow_10[y * N / 2 + x];
      }
    }

    return p;
  }

  bool operator==(card const &rhs) const {
    return static_cast<long long int>(*this) == static_cast<long long int>(rhs);
  }

  bool operator<(card const &rhs) const {
    return static_cast<long long int>(*this) < static_cast<long long int>(rhs);
  }

private:
  void to_down() {
    if (y0_ == 0) {
      swap(num_[y0_][x0_], num_[y0_ + 1][x0_]);
      ++y0_;
    }
  }

  void to_up() {
    if (y0_ == 1) {
      swap(num_[y0_][x0_], num_[y0_ - 1][x0_]);
      --y0_;
    }
  }

  void to_right() {
    if (x0_ != N / 2 - 1) {
      swap(num_[y0_][x0_], num_[y0_][x0_ + 1]);
      ++x0_;
    }
  }

  void to_left() {
    if (x0_ != 0) {
      swap(num_[y0_][x0_], num_[y0_][x0_ - 1]);
      --x0_;
    }
  }

private:
  int num_[2][4];
  int x0_, y0_;
};

int main() {
  int const start[N] = {0, 1, 2, 3, 4, 5, 6, 7};
  int const goal[N] = {7, 6, 5, 4, 3, 2, 1, 0};

  map<card, bool> memo;
  map<card, int> costs;
  queue<pair<int, card>> q;
  q.push(make_pair(0, card(start)));

  // loop
  while (!q.empty()) {
    int const cost = q.front().first;
    card const c = q.front().second;
    q.pop();

    if (memo[c])
      continue;
    memo[c] = true;
    costs[c] = cost;

    for (int i = 0; i < 4; ++i) {
      card const nc = c.make_moved(i);
      if (nc == c)
        continue;
      q.push(make_pair(cost + 1, nc));
    }
  }

  for (int r = 0; r < 1000; ++r) {
    int nn[N];
    for (int i = 0; i < N; ++i) {
      cin >> nn[i];
      if (cin.eof())
        return 0;
    }
    card const f(nn);

    cout << costs.at(f) << endl;
  }
}

Error: TLE

Fixed submission:

#include <cmath>
#include <iostream>
#include <map>
#include <queue>
#include <sstream>
#include <string>

using namespace std;

const int N = 8;

class card {
public:
  template <typename T> card(T const &t) {
    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < N / 2; ++j) {
        num_[i][j] = t[i * N / 2 + j];
        if (num_[i][j] == 0) {
          x0_ = j;
          y0_ = i;
        }
      }
    }
  }

public:
  card make_moved(int const dir) const {
    card ret(*this);

    switch (dir) {
    case 0:
      ret.to_up();
      break;
    case 1:
      ret.to_right();
      break;
    case 2:
      ret.to_down();
      break;
    case 3:
      ret.to_left();
      break;
    }

    return ret;
  }

public:
  operator double() const {
    double p = 0.0;

    for (int i = 0; i < 2; ++i) {
      for (int j = 0; j < N / 2; ++j) {
        p += static_cast<double>(num_[i][j]) * pow(10.0, i * N / 2 + j);
      }
    }

    return p;
  }

  bool operator==(card const &rhs) const {
    return static_cast<double>(*this) == static_cast<double>(rhs);
  }

  bool operator<(card const &rhs) const {
    return static_cast<double>(*this) < static_cast<double>(rhs);
  }

private:
  void to_down() {
    if (y0_ == 0) {
      swap(num_[y0_][x0_], num_[y0_ + 1][x0_]);
      ++y0_;
    }
  }

  void to_up() {
    if (y0_ == 1) {
      swap(num_[y0_][x0_], num_[y0_ - 1][x0_]);
      --y0_;
    }
  }

  void to_right() {
    if (x0_ != N / 2 - 1) {
      swap(num_[y0_][x0_], num_[y0_][x0_ + 1]);
      ++x0_;
    }
  }

  void to_left() {
    if (x0_ != 0) {
      swap(num_[y0_][x0_], num_[y0_][x0_ - 1]);
      --x0_;
    }
  }

private:
  int num_[2][4];
  int x0_, y0_;
};

int main() {
  int const goal[N] = {0, 1, 2, 3, 4, 5, 6, 7};

  for (int r = 0; r < 1000; ++r) {
    if (cin.eof())
      break;

    int nn[N];
    for (int i = 0; i < N; ++i) {
      cin >> nn[i];
    }
    card const start(nn);

    map<card, bool> memo;
    map<card, bool> collected, answers;

    queue<pair<int, card>> q;
    q.push(make_pair(0, card(goal)));

    int times = 0;

    // loop
    while (!q.empty()) {
      int const cost = q.front().first;
      card const c = q.front().second;
      q.pop();

      if (collected[c]) {
        times = answers[c] + cost;
        break;
      }

      if (c == start) {
        collected[c] = true;
        answers[c] = cost;
        times = cost;
        break;
      }

      for (int i = 0; i < 4; ++i) {
        card const nc = c.make_moved(i);
        if (nc == c || memo[nc])
          continue;

        memo[nc] = true;
        q.push(make_pair(cost + 1, nc));
      }
    }

    cout << times << endl;
  }
}