BFS之三(单向bfs和康托压缩)

//poj 1077 Eight

#include
<iostream> //单向bfs和康托压缩
#include<string>
using namespace std;

bool visited[1000000];
int fac[]={1,1,2,6,24,120,720,5040,40320,362880}; //9!表

int cantor(int arr[])
{
int temp,num=1; //当排列为1 2 3 4 5 6 7 8 9时康托值等于1
for(int i=0;i<9;++i)
{
temp
=0;
for(int j=i+1;j<9;++j)
if(arr[j]<arr[i])
temp
++;
num
+=fac[8-i]*temp;
}
return num;
}
void to_arr(int list[],int num)
{
int i;
for(i=0;i<9;++i)
list[i]
=0;
i
=8;
while(num)
{
list[i
--]=num%10;
num
/=10;
}
}
int to_num(int list[])
{
int n=0;
for(int i=0;i<9;++i)
n
=n*10+list[i];
return n;
}
struct node
{
char ch;
int pre; //通过pre记录路径,这样就不需开个string记录之前所走过的全部路径
int num; //通过num与arr相互转换,这样就不需开个数组记录当前的状态
int sub;
};
node table[
1000000];
//程序的空间开销是3348K,但单向bfs的运行时间会较多


int move[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
char pos[4]={'d','r','u','l'};

int main()
{
int arr[9];
char ch;
for(int i=0;i<9;++i)
{
cin
>>ch;
if(ch=='x')
arr[i]
=9,table[0].sub=i;
else
arr[i]
=int(ch-48);
}
table[
0].pre=-1;table[0].num=to_num(arr);
visited[cantor(arr)]
=1;
int head=0,rear=0;

while(head<=rear)
{
to_arr(arr,table[head].num);
if(cantor(arr)==1) //当排列为1 2 3 4 5 6 7 8 9时康托值等于1
{
string str;
int i=head;
while(i!=0)
{
str.insert(str.begin(),table[i].ch);
i
=table[i].pre;
}
cout
<<str<<endl;

return 0;
}
int x,y,tx,ty;
x
=table[head].sub/3;y=table[head].sub%3;

for(int i=0;i<4;++i)
{
tx
=x+move[i][0];ty=y+move[i][1];
if(tx>=0&&tx<3&&ty>=0&&ty<3)
{
swap(arr[x
*3+y],arr[tx*3+ty]);
if(visited[cantor(arr)]==0)
{
++rear;
table[rear].num
=to_num(arr);
table[rear].ch
=pos[i];
table[rear].pre
=head;
table[rear].sub
=tx*3+ty;
visited[cantor(arr)]
=1;
}
swap(arr[x
*3+y],arr[tx*3+ty]);
}
}
head
++;
}
cout
<<"unsolvable\n";
return 0;
}

  

posted on 2011-08-22 12:01  sysu_mjc  阅读(185)  评论(0编辑  收藏  举报

导航