实验要求:八数码难题也称九宫问题,它是在3×3的方格棋盘上,分别放置了表有数字1、2、3、4、5、6、7、8的八张牌,初始状态S0,目标状态Sg,要求程序能输入任意的初始状态和目标状态,要求通过空格来移动八张牌使得棋盘由初始状态到达目标状态。
**移动规则为:**每次只能将与空格(上下左右)相邻的一个数字平移到空格中。实验要求应用广度优先搜索策略寻找从初始状态到目标状态的解路径,编程语言为C系列语言。
完整代码如下:
#include<stdio.h>
struct node
{
int a[3][3];
int u;
int d;
int l;
int r;
int p;
};
int judge();
void search();
void up();
void down();
void left();
void right();
void output();
//typedef
node np[400000];
int target[3][3];
int f,r,zero_i,zero_j;
int x[100],y[100];
int main()
{
f=0;
r=0;
int i,j,n;
printf("请输入初始状态:\n");
n=0;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&np[0].a[i][j]);
if(np[0].a[i][j]!=0) x[n++]=np[0].a[i][j];
}
}
np[0].p=-1;
printf("请输入目标状态:\n");
n=0;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
scanf("%d",&target[i][j]);
if(target[i][j]!=0) y[n++]=target[i][j];
}
}
if(judge()==1)
{
search();
}
else printf("无法从该初始状态移动到目标状态\n");
return 0;
}
int judge()
{
int sum1=0,sum2=0,i,j;
for(i=1;i<8;i++)
{
for(j=0;j<i;j++)
{
if(x[i]>x[j]) sum1++;
if(y[i]>y[j]) sum2++;
}
}
if((sum1%2)==(sum2%2)) return 1;
else return 0;
}
void search()
{
int i,j,temp;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if(np[f].a[i][j]!=target[i][j]) break;
}
if(j<3) break;
}
if(i>=3&&j>=3) output();
else
{
// printf("111\n");
for(zero_i=0;zero_i<3;zero_i++)
{
for(zero_j=0;zero_j<3;zero_j++)
{
if(np[f].a[zero_i][zero_j]==0) break;
}
if(zero_j<3) break;
}
if(zero_i!=0) up();
if(zero_i!=2) down();
if(zero_j!=0) left();
if(zero_j!=2) right();
f++;
search();
}
}
void up()
{
int i,j;
r++;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if((i==zero_i&&j==zero_j)) np[r].a[i][j]=np[f].a[zero_i-1][j];
else if((i==zero_i-1&&j==zero_j)) np[r].a[i][j]=np[f].a[zero_i][j];
else np[r].a[i][j]=np[f].a[i][j];
}
}
np[r].p=f;
np[f].u=r;
}
void down()
{
int i,j;
r++;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if((i==zero_i&&j==zero_j)) np[r].a[i][j]=np[f].a[zero_i+1][j];
else if((i==zero_i+1&&j==zero_j)) np[r].a[i][j]=np[f].a[zero_i][j];
else np[r].a[i][j]=np[f].a[i][j];
}
}
np[r].p=f;
np[f].d=r;
}
void left()
{
int i,j;
r++;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if((i==zero_i&&j==zero_j)) np[r].a[i][j]=np[f].a[zero_i][zero_j-1];
else if((i==zero_i&&j==zero_j-1)) np[r].a[i][j]=np[f].a[zero_i][zero_j];
else np[r].a[i][j]=np[f].a[i][j];
}
}
np[r].p=f;
np[f].l=r;
}
void right()
{
int i,j;
r++;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
{
if((i==zero_i&&j==zero_j)) np[r].a[i][j]=np[f].a[zero_i][zero_j+1];
else if((i==zero_i&&j==zero_j+1)) np[r].a[i][j]=np[f].a[zero_i][zero_j];
else np[r].a[i][j]=np[f].a[i][j];
}
}
np[r].p=f;
np[f].r=r;
}
void output()
{
int i,j,n,m,temp,b[1000];
char ch[1000];
n=f;
m=0;
b[m]=f;
while(np[n].p!=-1)
{
//b[m+1]=np[n].p;
temp=n;
n=np[n].p;
if(np[n].u==temp) ch[m]='U';
if(np[n].d==temp) ch[m]='D';
if(np[n].l==temp) ch[m]='L';
if(np[n].r==temp) ch[m]='R';
m++;
b[m]=np[temp].p;
}
m--;
for(i=0;i<3;i++)
{
printf(" ");
for(j=0;j<3;j++) printf("%d ",np[0].a[i][j]);
printf("\n");
}
printf("\n");
while(m>=0)
{
printf("%c ",ch[m]);
for(i=0;i<3;i++)
{
for(j=0;j<3;j++) printf("%d ",np[b[m]].a[i][j]);
printf("\n");
printf(" ");
}
printf("\n");
m--;
}
}