Problem:
7 パズル

7 パズルは 8 つの正方形のカードとこれらのカードがぴたりと収まる枠で構成されています。それぞれのカードには、互いに区別できるように 0, 1, 2, ..., 7 と番号がつけられています。枠には、縦に 2 個、横に 4 個のカードを並べることができます。

7 パズルを始めるときには、まず枠にすべてのカードを入れます。枠のなかで 0 のカードだけは、上下左右に隣接するカードと位置を交換することができます。たとえば、枠の状態が図(a) のときに、0 のカードの右に隣接した、7 のカードと位置を交換すれば、図(b) の状態になります。あるいは、図(a) の状態から 0 のカードの下に隣接した 2 のカードと位置を交換すれば図(c) の状態になります。図(a) の状態で 0 のカードと上下左右に隣接するカードは 7 と 2 のカードだけなので、これ以外の位置の入れ替えは許されません。

ゲームの目的は、カードをきれいに整列して図(d) の状態にすることです。最初の状態を入力とし、カードをきれいに整列するまでに、必要な最小手数を出力するプログラムを作成してください。ただし、入力されたカードの状態からは図(d) の状態に移ることは可能であるとします。

入力データは、1 行に 8 つの数字が空白区切りで与えられます。これらは、最初の状態のカードの並びを表します。例えば、図(a) の数字表現は0 7 3 4 2 5 1 6 に、図(c) は 2 7 3 4 0 5 1 6 となります。

図(a) 0 7 3 4 2 5 1 6 の場合

図(b) 7 0 3 4 2 5 1 6 の場合

図(c) 2 7 3 4 0 5 1 6 の場合

図(d) 0 1 2 3 4 5 6 7 (最終状態)

Input

上記形式で複数のパズルが与えられます。入力の最後まで処理してください。
与えられるパズルの数は 1,000 以下です。

Output

各パズルについて、最終状態へ移行する最小手数を１行に出力してください。

Sample Input

0 1 2 3 4 5 6 7
1 0 2 3 4 5 6 7
7 6 5 4 3 2 1 0

Output for the Sample Input

0
1
28

Solution in C (judge verdict: Time Limit Exceeded)

#include<stdio.h>
int strint(int* a){
  int n,i;
  for(i=n=0;i<8;i++)n=n*10+a[i];
  return n;
}
void intstr(int n,int* s){
  int j;
  for(j=8;j--;n/=10)s[j]=n%10;
}
int stpint(int *n){
  int i,j,r=0,c,a[8]={1,1,1,1,1,1,1,1};
  int k=8*7*6*5*4*3*2*1;
  for(i=0;i<8;i++){
    k/=8-i;
    for(j=c=0;j<n[i];j++)c+=a[j];
    r+=c*k;
    a[j]=0;
  }
  return r;
}
int main(){
  int C[]={-4,-1,1,4};
  int q[50000],t,r,d[8],a[50000],i,j,k,c,m;
  int from[50000]={-1};
  while(~scanf("%d",&d[0])){
    int f[56*6*120]={0};
    for(i=1;i<8;i++)scanf("%d",&d[i]);
    f[stpint(d)]=1;
    q[t=a[0]=0]=strint(d);
    for(r=1;r-t;t++){//if(r>10)break;
      if(q[t]==1234567)break;
      for(i=0;i<4;i++){
	intstr(q[t],d);
	for(j=0;j<8;j++){
	  if(d[j]==0)break;
	}//printf("%d",j);
	//printf("%d\n",q[t]);
	c=j+C[i];
	if(c<0||7<c||c+j==7)continue;
	m=d[j];
	d[j]=d[c];
	d[c]=m;
	m=stpint(d);
	if(f[m])continue;
	f[m]=1;
	a[r]=a[t]+1;
	from[r]=t;
	q[r++]=strint(d);//printf("%08d %2d:",q[r-1],a[r-1]);	
      }//printf("\n");
    }
    printf("%d\n",a[t]);
    //for(i=t;t+1;t=from[t])printf("%08d %2d\n",q[t],a[t]);
  }
  return 0;
}