双向广搜(DBFS)

双向广搜很早之前就像学习,但蒟蒻这道今天才会写(汗。。。)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

八数码问题在oi界也算是妇孺皆知,有启发式搜索和DBFS两种解法,题目不在详细介绍,在这里给出我的解法

codevs 1225 八数码难题

比较原始的八数码,目标状态为123804765(即蛇形排列),双向广搜顾名思义,就是两头同时进行广搜,我们有了起点状态和目标状态,可以同时扩展,这道扩展出同一个叶子节点,注意hash判重,queue中的st为步数,col表示是从正序扩展而来还是从逆序扩展而来,exist存放编号,一旦出现hash值相同但col不同,就查询出来节点编号,把st相加即为结果。 code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
int en[4][4]={0,0,0,0,0,1,2,3,0,8,0,4,0,7,6,5},st[4][4],head,tail;
int dx[5]={0,1,0,-1,0},dy[5]={0,0,1,0,-1};
int exist[500001][2];
struct hp{
	int map[4][4],bx,by,col,st;
}queue[500001];
int hash(int i)
{
	int j,k,m,p,sum=0,x;
	for (j=1;j<=3;++j)
	  for (k=1;k<=3;++k)
	    {
	      x=0;
		  for (p=k+1;p<=3;++p)
		    x+=queue[i].map[j][k]>queue[i].map[j][p];
		  for (p=j+1;p<=3;++p)
		    for (m=1;m<=3;++m)
			  x+=queue[i].map[j][k]>queue[i].map[p][m];
		  sum+=x*fac[9-(j-1)*3-k];	
	    }
	return sum;
}
void init()
{
	int i,j;
	char c;
	for (i=1;i<=3;++i)
	  for (j=1;j<=3;++j)
	    {
	      scanf("%c",&c);
	      st[i][j]=int(c)-48;
	    }
}
int bfs()
{
	int bx1,by1,i,j,k,m,e,step,temp,std;
	head=0; tail=2;
	for (i=1;i<=3;++i)
	  for (j=1;j<=3;++j)
	    {
	      queue[2].map[i][j]=en[i][j];
	      queue[1].map[i][j]=st[i][j];
	      if (st[i][j]==0)
	        {
	          queue[1].bx=i;
	          queue[1].by=j;
	        }
	      if (en[i][j]==0)
	        {
	          queue[2].bx=i;
	          queue[2].by=j;
	        }
	    }
	queue[1].col=0; queue[2].col=1;
	queue[1].st=queue[2].st=0;
	memset(exist,0,sizeof(exist));
	exist[hash(1)][0]=1; exist[hash(2)][1]=2; step=0;
	while (head<tail)
	  {
	    e=tail; head++; step++;
	    for (i=head;i<=e;++i)
	      {
	      	bx1=queue[i].bx;
	      	by1=queue[i].by;
	        for (j=1;j<=4;++j)
	          if (bx1+dx[j]>=1&&bx1+dx[j]<=3&&by1+dy[j]>=1&&by1+dy[j]<=3)
			    {
			      tail++;
		          for (k=1;k<=3;++k)
				    for (m=1;m<=3;++m)
					  queue[tail].map[k][m]=queue[i].map[k][m];
				  queue[tail].bx=bx1+dx[j];
				  queue[tail].by=by1+dy[j];
				  queue[tail].map[bx1+dx[j]][by1+dy[j]]=0;
				  queue[tail].map[bx1][by1]=queue[i].map[bx1+dx[j]][by1+dy[j]];
				  queue[tail].col=queue[i].col;
				  queue[tail].st=step;
				  temp=hash(tail);
				  if (exist[temp][queue[tail].col]) 
				    tail--;
				  else
				    {
				      exist[temp][queue[tail].col]=tail;
				      if (exist[temp][1-queue[tail].col])
				        return step+queue[exist[temp][1-queue[tail].col]].st;
				    }  
			    }  
	      }
	    head=e;
	  }
	return -1;
}
int main()
{
	int num;
	init();
	num=bfs();
	if (num!=-1)
	  printf("%d\n",num);
	else
	  printf("unsolvable\n");
}
poj 1077 Eight 输出路径的八数码,稍麻烦 code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
int en[4][4]={0,0,0,0,0,1,2,3,0,4,5,6,0,7,8,0},st[4][4],head,tail;
int dx[5]={0,1,0,-1,0},dy[5]={0,0,1,0,-1};
int exist[500001][2];
struct hp{
	int map[4][4],bx,by,col,st,last;
	char mov;
}queue[500001];
int hash(int i)
{
	int j,k,m,p,sum=0,x;
	for (j=1;j<=3;++j)
	  for (k=1;k<=3;++k)
	    {
	      x=0;
		  for (p=k+1;p<=3;++p)
		    x+=queue[i].map[j][k]>queue[i].map[j][p];
		  for (p=j+1;p<=3;++p)
		    for (m=1;m<=3;++m)
			  x+=queue[i].map[j][k]>queue[i].map[p][m];
		  sum+=x*fac[9-(j-1)*3-k];	
	    }
	return sum;
}
void init()
{
	int i,j;
	char c;
	for (i=1;i<=3;++i)
	  for (j=1;j<=3;++j)
	    {
	      scanf("%c",&c);
	      if (c==' ')
	        scanf("%c",&c);
	      if (c!='x')
	        st[i][j]=int(c)-48;
	      else
	        st[i][j]=0;
	    }
}
void print1(int mid)
{
	if (queue[mid].last!=1)
	  print1(queue[mid].last);
	printf("%c",queue[mid].mov);
}
void print2(int mid)
{
	printf("%c",queue[mid].mov);
	if (queue[mid].last!=2)
	  print2(queue[mid].last); 
}
int bfs()
{
	int bx1,by1,i,j,k,m,e,step,temp,std;
	head=0; tail=2;
	for (i=1;i<=3;++i)
	  for (j=1;j<=3;++j)
	    {
	      queue[2].map[i][j]=en[i][j];
	      queue[1].map[i][j]=st[i][j];
	      if (st[i][j]==0)
	        {
	          queue[1].bx=i;
	          queue[1].by=j;
	        }
	      if (en[i][j]==0)
	        {
	          queue[2].bx=i;
	          queue[2].by=j;
	        }
	    }
	queue[1].col=0; queue[2].col=1;
	queue[1].st=queue[2].st=0;
	memset(exist,0,sizeof(exist));
	exist[hash(1)][0]=1; exist[hash(2)][1]=2; step=0;
	while (head<tail)
	  {
	    e=tail; head++; step++;
	    for (i=head;i<=e;++i)
	      {
	      	bx1=queue[i].bx;
	      	by1=queue[i].by;
	        for (j=1;j<=4;++j)
	          if (bx1+dx[j]>=1&&bx1+dx[j]<=3&&by1+dy[j]>=1&&by1+dy[j]<=3)
			    {
			      tail++;
		          for (k=1;k<=3;++k)
				    for (m=1;m<=3;++m)
					  queue[tail].map[k][m]=queue[i].map[k][m];
				  queue[tail].bx=bx1+dx[j];
				  queue[tail].by=by1+dy[j];
				  queue[tail].map[bx1+dx[j]][by1+dy[j]]=0;
				  queue[tail].map[bx1][by1]=queue[i].map[bx1+dx[j]][by1+dy[j]];
				  queue[tail].col=queue[i].col;
				  queue[tail].st=step;
				  queue[tail].last=i;
				  if (queue[tail].col==0)
				    {
				      if (j==1) queue[tail].mov='d';
				      if (j==2) queue[tail].mov='r';
				      if (j==3) queue[tail].mov='u';
				      if (j==4) queue[tail].mov='l';
				    }
			      if (queue[tail].col==1)
			        {
			          if (j==1) queue[tail].mov='u';
			          if (j==2) queue[tail].mov='l';
			          if (j==3) queue[tail].mov='d';
			          if (j==4) queue[tail].mov='r';
			        }
				  temp=hash(tail);
				  if (exist[temp][queue[tail].col]) 
				    tail--;
				  else
				    {
				      exist[temp][queue[tail].col]=tail;
				      if (exist[temp][1-queue[tail].col])
				        {
				          if (queue[tail].col==0)
				            {
				              print1(tail);
				              print2(exist[temp][1-queue[tail].col]);
				            }
				          else
				            {
				              print1(exist[temp][1-queue[tail].col]);
				              print2(tail);
				            }
				          return step+queue[exist[temp][1-queue[tail].col]].st;
				        }
				    }  
			    }  
	      }
	    head=e;
	  }
	return -1;
}
int main()
{
	int num;
	init();
	num=bfs();
	if (num==-1)
	  printf("unsolvable\n");
}

你可能感兴趣的:(双向广搜(DBFS))