宽搜,模拟0向上下左右四个方向的移动,
数据4*4 , 判重可以把矩阵转成2进制判重
code:
/**************************************************************
Problem: 1054
Language: C++
Result: Accepted
Time:2024 ms
Memory:16116 kb
****************************************************************/
// Forever_LF
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int dx[4]={-1,0,1, 0};
const int dy[4]={ 0,1,0,-1};
struct node
{
int a[6][6],num;
node(){ num = 0; }
}ed,list[100000]; int k,head,tail;
bool v[6][6];
int appear[100000],r,ans;
int Z( node x )
{
int i,j,l;
l=0;
for( i=1;i<=4;i++ )
for( j=1;j<=4;j++ )
l = l *2 + x.a[i][j];
return l;
}
bool pd( node x )
{
int tmp=0,i,j;
bool v=true;
tmp = Z( x );
if( tmp == ans )
{
k = x.num;
return true;
}
for( i=1;i<=r;i++ )
if( tmp == appear[i] )
{
v = false;
break;
}
if( v ) appear[ ++r ] = tmp;
return v;
}
void bfs( )
{
int i,j,l,xx,yy;
head = tail = 1;
while( head<=tail )
{
node x = list[head];
for( i=1;i<=4;i++ )
for( j=1;j<=4;j++ )
if( x.a[i][j] == 0 )
for( l=0;l<4;l++ )
{
xx = i+dx[l];
yy = j+dy[l];
if( v[xx][yy] )
{
node y=x;
y.num++;
y.a[xx][yy] = x.a[i][j];
y.a[i][j] = x.a[xx][yy];
if( pd( y ) ) list[++tail] = y;
if( k ) return;
}
}
head++;
}
return;
}
int main()
{
int i,j;
char s;
for( i=0;i<=5;i++ )
for( j=0;j<=5;j++ )
v[i][j] = false;
for( i=1;i<=4;i++ )
{
for( j=1;j<=4;j++ )
{
scanf("%c",&s);
list[1].a[i][j] = s-48;
v[i][j]=true;
}
getchar();
}
getchar();
for( i=1;i<=4;i++ )
{
for( j=1;j<=4;j++ )
{
scanf("%c",&s);
ed.a[i][j] = s-48;
}
getchar();
}
ans = Z( ed );
appear[ ++r ] = Z( list[1] );
if( ans == appear[1] ) { printf("0\n");return 0; }
bfs();
printf( "%d\n",k );
return 0;
}