双向广搜很早之前就像学习,但蒟蒻这道今天才会写(汗。。。)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
八数码问题在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"); }