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

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

#define inRange(idx, hi, low) (low <= idx && idx < hi)

using namespace std;

typedef pair<string, int> Pair;

struct Puzzle {
  int count;
  int zero;
  string field;
};

void swap(string &str, int a, int b) {
  char tmp = str[a];
  str[a] = str[b];
  str[b] = tmp;
}

map<string, int> field;

void search(void) {
  int d[][4] = {{-1, 1, 4}, {-1, 1, -4}};
  string start = "01234567";
  Puzzle tmp;
  queue<Puzzle> q;
  int in = 0;
  field[start] = 0;
  tmp.count = tmp.zero = 0;
  tmp.field = start;
  q.push(tmp);
  while (!q.empty()) {
    tmp = q.front();
    q.pop();
    for (int i = 0; i < 3; ++i) {
      int idx = tmp.zero + d[tmp.zero / 4][i];
      int hi = 8, low = 0;
      if (tmp.zero < 4 && d[tmp.zero / 4][i] == 1)
        hi = 4;
      else if (tmp.zero > 3 && d[tmp.zero / 4][i] == -1)
        low = 4;
      if (inRange(idx, hi, low)) {
        Puzzle work = tmp;
        swap(work.field, tmp.zero, idx);
        if (!field.count(work.field)) {
          ++work.count;
          work.zero = idx;
          q.push(work);
          field[work.field] = work.count;
        }
      }
    }
  }
}

int main(void) {
  search();
  string input, str;
  while (cin >> input) {
    str += input;
    for (int i = 0; i < 7; ++i) {
      cin >> input;
      str += input;
    }
    cout << field[str] << endl;
    str = "";
  }

  return 0;
}

Error: TLE

Fixed submission:

#include <iostream>
#include <queue>
#include <set>

#define inRange(x, y, w, h) (0 <= x && x < w && 0 <= y && y < h)
#define idx_x(n, w) (n % w)
#define idx_y(n, w) (n / w)
#define idx(x, y, w) (y * w + x)
#define SIZE 8

using namespace std;

bool judge(int *map) {
  for (int i = 0; i < SIZE; ++i)
    if (*(map + i) != i)
      return false;
  return true;
}

struct puzzle {
  int count;
  int map[SIZE];
};
bool operator<(const puzzle &a, const puzzle &b) {
  for (int i = 0; i < SIZE; ++i) {
    if (a.map[i] < b.map[i])
      return true;
    else if (a.map[i] > b.map[i])
      return false;
  }
  return false;
}

int main(void) {
  int dx[] = {0, 0, -1, 1};
  int dy[] = {-1, 1, 0, 0};

  while (true) {
    queue<puzzle> q;
    set<puzzle> s;
    puzzle input;
    bool eof = false;
    for (int i = 0; i < SIZE; ++i) {
      int n;
      if (cin >> n)
        input.map[i] = n;
      else
        eof = true;
    }
    if (eof)
      break;
    if (judge(input.map))
      cout << 0 << endl;
    else {
      input.count = 0;
      q.push(input);
      s.insert(input);
      while (!q.empty()) {
        puzzle map = q.front();
        q.pop();
        for (int i = 0; i < SIZE; ++i) {
          if (!map.map[i]) {
            for (int k = 0; k < 4; ++k) {
              int mx = idx_x(i, 4) + dx[k];
              int my = idx_y(i, 4) + dy[k];
              if (inRange(mx, my, 4, 2)) {
                puzzle tmp;
                tmp = map;
                ++tmp.count;
                swap(tmp.map[i], tmp.map[idx(mx, my, 4)]);
                if (judge(tmp.map)) {
                  cout << tmp.count << endl;
                  goto END;
                } else if (!s.count(tmp)) {
                  s.insert(tmp);
                  q.push(tmp);
                }
              }
            }
            break;
          }
        }
      }
    END:;
    }
  }
  return 0;
}