Eight Puzzle
做了此题,更加深深感觉到了咱们oj数据的强大威力,在其他oj绝对能过的到了这里TLE(其实发生过很多回了)
此题运用广度优先搜索+hash(康托展开)
此题的常规做法是开一个9*9*9*9*9*9*9*9*9 的数组用于存储状态 但是这是极大的浪费事实上也是不可能的
超内存的
因此就要用到hash来进行处理,运用康拓展开来实现的原理是一个数的阶乘(9!)可以表示成(0-----8!*7 + 7!*6 + 6!*5 + 1!*0)
此区间的数一一对应,于是只开一个9!的数组就行了 空间是足够的
还有一个十分重要的剪枝也许在其他oj不需要但是在我们oj是必不可少的,就是因为有多组数据,在广度搜素过程中因为一次有30多万的状态
多搜几次就超时了,怎么办呢?
逆着搜,只搜索一遍 然后记录下从目标状态到初始状态的最短路径,然后只是需要O(1)的时间的复杂度就可以完成了。
做了此题,更加深深感觉到了咱们oj数据的强大威力,在其他oj绝对能过的到了这里TLE(其实发生过很多回了)
此题运用广度优先搜索+hash(康托展开)
此题的常规做法是开一个9*9*9*9*9*9*9*9*9 的数组用于存储状态 但是这是极大的浪费事实上也是不可能的
超内存的
因此就要用到hash来进行处理,运用康拓展开来实现的原理是一个数的阶乘(9!)可以表示成(0-----8!*7 + 7!*6 + 6!*5 + 1!*0)
此区间的数一一对应,于是只开一个9!的数组就行了 空间是足够的
还有一个十分重要的剪枝也许在其他oj不需要但是在我们oj是必不可少的,就是因为有多组数据,在广度搜素过程中因为一次有30多万的状态
多搜几次就超时了,怎么办呢?
逆着搜,只搜索一遍 然后记录下从目标状态到初始状态的最短路径,然后只是需要O(1)的时间的复杂度就可以完成了。
#include<cstdio>
#include<cstring>
struct node
{
int state[3][3];
int step;
}que[362881];
int hash[362881][2];
int a[9];
int b[3][3];
char str[20];
char map[3][3];
int dir[4][2]={1,0,-1,0,0,-1,0,1};
int f[9]={1,1,2,6,24,120,720,5040,40320};
int hash_res()
{
int k = 0;
int res=0,i,j;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
a[k++]=b[i][j];
for(int i=0;i<9;i++)
{ int num=0;
for(int j=0;j<i;j++)
if(a[j]>a[i]) num++;
res+=f[i]*num;
}
return res;
}
void bfs()
{
int front =0,rear =0,i,j;
memset(hash,0,sizeof(hash));
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
if(map[i][j]=='x')
que[rear].state[i][j]=9;
else
que[rear].state[i][j]=map[i][j]-'0';
}
for(i=0;i<3;i++)
for(j=0;j<3;j++)
b[i][j]=que[rear].state[i][j];
hash[hash_res()][0]=1;
hash[hash_res()][1]=0;
que[rear].step = 0;
rear++;
while(front<rear)
{
int x,y;
node head = que[front];
front++;
for(i=0;i<3;i++)
for(j=0;j<3;j++)
{
b[i][j]=head.state[i][j];
if(b[i][j]==9)
{
x = i; y = j;
}
}
for(i=0;i<4;i++)
{
int ii,jj;
int nx = x + dir[i][0];
int ny = y + dir[i][1];
if(nx>=0&&ny>=0&&nx<3&&ny<3)
{
int temp;
temp = b[nx][ny];
b[nx][ny] = b[x][y];
b[x][y] = temp;
if(hash[hash_res()][0]==0)
{
for(ii=0;ii<3;ii++)
for(jj=0;jj<3;jj++)
que[rear].state[ii][jj]=b[ii][jj];
hash[hash_res()][0]=1;
hash[hash_res()][1]=head.step+1;
que[rear].step=head.step+1;
rear++;
}
temp = b[nx][ny];
b[nx][ny] = b[x][y];
b[x][y] = temp;
}
}
}
}
int main()
{
map[0][0]='1';
map[0][1]='2';
map[0][2]='3';
map[1][0]='4';
map[1][1]='5';
map[1][2]='6';
map[2][0]='7';
map[2][1]='8';
map[2][2]='9';
bfs();
while(gets(str))
{
int m = 0;
for(int i=0;i<3;i++)
for(int j =0;j<3;j++)
{
b[i][j]=str[m]-'0';
m+=2;
}
int res =hash_res();
if(res !=0&&hash[hash_res()][1]!=0)
printf("%d\n",hash[hash_res()][1]);
else if(res==0)
printf("%d\n",hash[hash_res()][1]);
else printf("unsolvable\n");
}
return 0;
}