1、题目类型:模拟、哈希表、BFS。
2、解题思路:(1)模拟Eigh Puzzle的变换方式,并记录在数组中 ;(2)由于变换的最终结果相同,所以采用反向的BFS遍历所有情况,并记录所有情况;(3)在查找情况过程中采用二进制哈希表形式,以便于查找;(4)根据题目每个输入的case对表中进行对应查找,直接输出答案。
3、注意事项:注意哈希表方式,否则TLE。
4、实现方法:(由于又借用模板,所以代码有点乱)
#include < iostream >
#include < string >
using namespace std;
const int r[] = { 0 , 1 , 4 , 3 , 0 , 3 , 4 , 1 , 1 , 2 , 5 , 4 , 1 , 4 , 5 , 2 , 3 , 4 , 7 , 6 , 3 , 6 , 7 , 4 , 4 , 5 , 8 , 7 , 4 , 7 , 8 , 5 };
int final[] = { 69074 , 77576 , 135289 , 157120 , 205759 , 227590 , 285303 , 293805 };
int p[] = { 1 , 1 , 2 , 6 , 24 , 120 , 720 , 5040 , 40320 };
int d[ 362880 ], q[ 362880 ];
int s[ 9 ];
int Encode( int * s)
{
int i,j,k,x = 0 ;
for (i = 0 ;i < 9 ;i ++ )
{
k = s[i];
for (j = 0 ;j < i;j ++ )
if (s[j] < s[i])
k -- ;
x += k * p[ 8 - i];
}
return x;
}
void Decode( int * s, int x)
{
int i,j;
for (i = 0 ;i < 9 ;i ++ )
{
s[i] = x / p[ 8 - i];
x %= p[ 8 - i];
}
for (i = 8 ;i >= 0 ;i -- )
for (j = 8 ;j > i;j -- )
if (s[j] >= s[i])
s[j] ++ ;
}
void Init()
{
int i,x,y,front,rear,ss[ 9 ];
memset(d, - 1 , sizeof (d));
for (i = 0 ;i < 9 ;i ++ )
ss[i] = i;
q[ 0 ] = Encode(ss);
d[q[ 0 ]] = 0 ;
front = 0 , rear = 1 ;
while (front < rear)
{
x = q[front ++ ];
Decode(s,x);
{
for (i = 0 ;i < 9 ;i ++ )
{
if (s[i] == 8 )
break ;
}
if (i != 0 && i != 1 && i != 2 )
{
s[i] = s[i - 3 ];
s[i - 3 ] = 8 ;
y = Encode(s);
if (d[y] < 0 )
{
d[y] = d[x] + 1 ;
q[rear ++ ] = y;
}
s[i - 3 ] = s[i];
s[i] = 9 ;
}
if (i != 2 && i != 5 && i != 8 )
{
s[i] = s[i + 1 ];
s[i + 1 ] = 8 ;
y = Encode(s);
if (d[y] < 0 )
{
d[y] = d[x] + 1 ;
q[rear ++ ] = y;
}
s[i + 1 ] = s[i];
s[i] = 8 ;
}
if (i != 6 && i != 7 && i != 8 )
{
s[i] = s[i + 3 ];
s[i + 3 ] = 8 ;
y = Encode(s);
if (d[y] < 0 )
{
d[y] = d[x] + 1 ;
q[rear ++ ] = y;
}
s[i + 3 ] = s[i];
s[i] = 8 ;
}
if (i != 0 && i != 3 && i != 6 )
{
s[i] = s[i - 1 ];
s[i - 1 ] = 8 ;
y = Encode(s);
if (d[y] < 0 )
{
d[y] = d[x] + 1 ;
q[rear ++ ] = y;
}
s[i - 1 ] = s[i];
s[i] = 8 ;
}
}
}
}
int main()
{
int i,T;
char ch;
Init();
cin >> T;
while (T -- )
{
for (i = 0 ;i < 9 ;i ++ )
{
cin >> ch;
if (ch == ' # ' )
s[i] = 8 ;
else
s[i] = ch - ' 1 ' ;
}
if (d[Encode(s)] !=- 1 )
cout << d[Encode(s)] << endl;
else
cout << " impossible " << endl;
}
return 0 ;
}