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 (judge verdict: Time Limit Exceeded)

#include <stdio.h>
#include <stdlib.h>
 
#define tate 3
#define yoko 3
#define Total (tate*yoko)


extern void down_0(void);
extern void up_0(void);
extern void right_0(void);
extern void left_0(void);
extern int  serch(int x, int y, int MaxCnt);
extern int  check(void);

int cnt,num = 0;
int val[Total] ={};


int main( void )
{
 
    int ori[Total] ={};
    
    
    int i = 0;
    int num_0 = 0;
    int x,y = 0;
     
    for(i=0; i<Total; i++)
    {
        scanf("%d",&val[i]);
        ori[i]=val[i];
        
        if(val[i] == 0)
        {
            num_0 = i;
        }
    }
    
    x = tate - (num_0/yoko);
    y = yoko - (num_0%yoko);
    
        // 初期化
        for(i=0; i<Total; i++)
        {
            val[i]=ori[i];
        }
        num = num_0;
        cnt = 0;
        
    for(i=1; i<35; i++)
    {
        if( serch(x,y,i) )
        {
            printf("%d\n",i);
            break;
        }
    }
        
//  printf("%d%d%d%d%d%d%d%d%d\n", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8]);        
    
    return 0;
}

int serch(int x, int y, int MaxCnt)
{
    int result;
    int i=0;
    
    // 最大数で打ち切り
    if(cnt >= MaxCnt)
    {
        return check();
    }
    
    //
    if(x==0 && y==0)
    {
        if( check() )
        {
            return 1;
        }
    }
    
    // 上下左右で4回回す
    for(i=0; i<4; i++)
    {
        result = 0;
        
        switch(i)
        {
            case 0:
                if(x != 0)
                {
                    down_0();
                    x = x-1;
                    
                    cnt = cnt + 1;
                    result = serch(x,y,MaxCnt);
                    cnt=cnt-1;
                    
                    up_0();
                    x = x+1;
                }
                break;
            case 1:
                if(y != 0)
                {
                    right_0();
                    y = y-1;
                    
                    cnt = cnt + 1;
                    result = serch(x,y,MaxCnt);
                    cnt=cnt-1;
                    
                    left_0();
                    y = y+1;
                }
                break;
            case 2:
                if(y < yoko-1)
                {
                    left_0();
                    y = y+1;
                    
                    cnt = cnt + 1;
                    result = serch(x,y,MaxCnt);
                    cnt=cnt-1;
                    
                    right_0();
                    y = y-1;
                }
                break;
            case 3:
                if(x < tate-1)
                {
                    up_0();
                    x = x+1;
                    
                    cnt = cnt + 1;
                    result = serch(x,y,MaxCnt);
                    cnt=cnt-1;
                    
                    down_0();
                    x = x-1;
                }
                break;
            default:
                break;
        }
        
        if(result)
        {
            return 1;
        }
        
    }

    return 0;
}

// TRUE : 完成
// FALSE : 失敗
int check()
{
    int i=0;
    
//    printf("%d%d%d%d%d%d%d%d%d\n", val[0], val[1], val[2], val[3], val[4], val[5], val[6], val[7], val[8]);
    
    for(i=0; i<Total-1; i++)
    {
        if(val[i] != (i+1))
        {
            return 0;
        }
    }
    return 1;
}

void down_0()
{
    val[num] = val[num + yoko];
    val[num + yoko] = 0;
    num = num + yoko;
}
 
void up_0()
{
    val[num] = val[num - yoko];
    val[num - yoko] = 0;
    num = num - yoko;
}
 
void right_0()
{
    val[num] = val[num +1];
    val[num +1] = 0;
    num = num + 1;
}
 
void left_0()
{
    val[num] = val[num -1];
    val[num -1] = 0;
    num = num - 1;
}