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: Accepted)

#include<stdio.h>
#include<stdlib.h>
#define N 9
#define INF 330000

int ans[N]={1,2,3,4,5,6,7,8,0};
int head=0,tail=0,cnt=0;

struct qu{
  int s[N];
};

struct node{
  int key;
  struct node *parent,*left,*right;
};

struct node *root,*NIL;
struct qu Q[INF];

void enqueue(struct qu x){

  int next=tail+1;
  Q[tail]=x;
  tail=next;
}
struct qu dequeue(void){
  struct qu x;

  x=Q[head];
  head=head+1;
  return x;
}

int find(struct node *u, int k){
  while(u!=NIL&&k!=u->key){
    if(k<u->key) u=u->left;
    else u=u->right;
  }
  if(u!=NIL) return 1;
  else return 0;
}

int insert(struct qu a){
  int k,i,j;

  for(i=0;i<=N;i++){
    if(i==0) k+=a.s[i];
    else{
      for(j=0;j<i;j++) a.s[i]*=10;
      k+=a.s[i];
    }
  }

  if(find(root,k)==1) return 0;

  struct node *y=NIL;  //xの親
  struct node *x=root;
  struct node *z;

  z=(struct node*)malloc(sizeof(struct node));

  z->key=k;
  z->left=NIL;
  z->right=NIL;

  while(x!=NIL){
    y=x;
    if(z->key<x->key) x=x->left;
    else x=x->right;
  }

  z->parent=y;

  if(y==NIL) root=z;
  else if(z->key<y->key) y->left=z;
  else y->right=z;

  return 1;
}

int trade(){
  int tmp,i,flag,loc,h[INF],sum;
  struct qu a,b,c,d,y;

  h[head]=0;

  while(1){

    sum=h[head];
    y=dequeue();

    flag=0;

    for(i=0;i<N;i++){
      if(y.s[i]!=ans[i]) flag=1;
      if(y.s[i]==0) loc=i; //０の位置を記録
    }
    if(flag==0) break;

    a=b=c=d=y;

    /*
      ０を移動させるとして　aは上　bは右　cは下　dは左
      条件を満たす場合０と交換して、ヒューリスティック探索を行う
    */
    if(loc%3!=0){tmp=a.s[loc-1]; a.s[loc-1]=0; a.s[loc]=tmp;
          if(insert(a)==1){ enqueue(a); h[tail-1]=(sum+1);}}

    if(loc%3!=2){ tmp=b.s[loc+1]; b.s[loc+1]=0; b.s[loc]=tmp;
      if(insert(b)==1){ enqueue(b); h[tail-1]=(sum+1);}}

    if(loc<6){tmp=c.s[loc+3]; c.s[loc+3]=0; c.s[loc]=tmp;
      if(insert(c)==1){ enqueue(c); h[tail-1]=(sum+1);}}

    if(loc>2){tmp=d.s[loc-3]; d.s[loc-3]=0; d.s[loc]=tmp;
      if(insert(d)==1){ enqueue(d); h[tail-1]=(sum+1);}}
  }

  return sum;
}

int main(){
  int i,j,sum,a;
  struct qu x;

  for(i=0;i<N;i++){
    scanf("%d",&x.s[i]);
  }

  insert(x);
  enqueue(x);
  sum=trade();

  printf("%d\n",sum);

  return 0;
}