Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

8 Puzzle

The goal of the 8 puzzle problem is to complete pieces on $3 \times 3$ cells where one of the cells is empty space.

In this problem, the space is represented by 0 and pieces are represented by integers from 1 to 8 as shown below.

1 3 0
4 2 5
7 8 6

You can move a piece toward the empty space at one step. Your goal is to make the pieces the following configuration in the shortest move (fewest steps).

1 2 3
4 5 6
7 8 0

Write a program which reads an initial state of the puzzle and prints the fewest steps to solve the puzzle.

Input

The $3 \times 3$ integers denoting the pieces or space are given.

Output

Print the fewest steps in a line.

Constraints

There is a solution.

Sample Input

1 3 0
4 2 5
7 8 6

Sample Output

4

Solution in C++11 (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>

#define REP(i, n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()
const int INF = 1e9;

using namespace std;
const int answer[9] = {1, 2, 3, 4, 5, 6, 7, 8, 0};
const bool dir[9][4] = {{false, false, true, true},
                        {true, false, true, true},
                        {true, false, true, false},
                        {false, true, true, true},
                        {true, true, true, true},
                        {true, true, true, false},
                        {false, true, false, true},
                        {true, true, false, true},
                        {true, true, false, false}}; /* left, up, down, right */
vector<int> original(9, 0);

class board;

priority_queue<board> pq;
vector<int> searched[9];

class board{
private:
    int moves;
    int wrongs;
    int zero_place;
    vector<int> tiles;

public:
    explicit board(vector<int> num, int move){
        wrongs = 0;
        REP(i, 9){
            tiles.push_back(num[i]);
            if(num[i] == 0)
                zero_place = i;
            if(num[i] != answer[i])
                wrongs++;
        }
        moves = move;
    }

    int cost() {
        return wrongs + moves;
    }

    void board_to_int(){
        int k = 0;
        REP(i, 9)
            k += (tiles[i] * pow(10, i));
        for(int i = searched[tiles[0]].size(); i > 0 ; i--)
            if(k == searched[tiles[0]][i-1])
                return;
        pq.push(board(tiles, moves+1));
        searched[tiles[0]].push_back(k);
        return;
    }

    void move() {
        if(dir[zero_place][0]){
            swap(tiles[zero_place], tiles[zero_place-1]);
            board_to_int();
            swap(tiles[zero_place], tiles[zero_place-1]);
        }
        if(dir[zero_place][1]){
            swap(tiles[zero_place], tiles[zero_place-3]);
            board_to_int();
            swap(tiles[zero_place], tiles[zero_place-3]);
        }
        if(dir[zero_place][2]){
            swap(tiles[zero_place], tiles[zero_place+3]);
            board_to_int();
            swap(tiles[zero_place], tiles[zero_place+3]);
        }
        if(dir[zero_place][3]){
            swap(tiles[zero_place], tiles[zero_place+1]);
            board_to_int();
            swap(tiles[zero_place], tiles[zero_place+1]);
        }
    }

    int get_wrongs(){
        return wrongs;
    }
};

bool operator< (board b1, board b2){
    return (b1.cost() > b2.cost()) ? true : false;
}

int solve(){
    pq.push(board(original, 0));
    while(!pq.empty()){
        auto target = pq.top();
        pq.pop();
        if(target.get_wrongs() == 0)
            return target.cost();
        target.move();
    }
    return -1;
}

int main() {
    REP(i, 9) cin >> original[i];
    int move = 0;
    move = solve();
    cout << move << endl;
    return 0;
}