数字华容道问题的设计与实现Word文件下载.docx
《数字华容道问题的设计与实现Word文件下载.docx》由会员分享,可在线阅读,更多相关《数字华容道问题的设计与实现Word文件下载.docx(9页珍藏版)》请在冰豆网上搜索。
![数字华容道问题的设计与实现Word文件下载.docx](https://file1.bdocx.com/fileroot1/2022-10/13/ddcde7ad-7403-4493-a70e-74e22bb751b4/ddcde7ad-7403-4493-a70e-74e22bb751b41.gif)
由文件input.txt给出输入数据。
文件的第1行有1个正整数n。
以下的n行是n×
n方格阵列的中数字1~n2-1的初始排列,每行有n个数字表示该行方格中的数字,0表示空格。
结果输出:
将计算出的最少移动次数和相应的移动序列输出到文件output.txt。
第1行是最少移动次数。
从第2行开始,依次输出移动序列。
三、源程序关键代码
#include<
stdio.h>
malloc.h>
stdlib.h>
#defineOverflow1
#defineN3
intgoal[N][N]={1,2,3,8,0,4,7,6,5};
intzero[2],NodeQTY=0;
int*z=zero;
//记录0的位置,zero[0]:
r行;
zero[1]:
c列
typedefintPiece;
structChessboard{//棋盘信息
Piecepos[N][N];
//记录每个数码a的位置r行c列
intd,f,move;
//d:
深度;
f:
启发函数值;
move:
父节点移动到该节点的方式
};
structLNode{
Chessboardboard;
LNode*parent,*next;
boolflag;
typedefLNode*List;
int*Findzero(LNode*&
Node)
{
inti,j,zr[2];
int*z=zr;
for(i=0;
i<
N;
i++){
for(j=0;
j<
j++){
if(Node->
board.pos[i][j]==0){
zr[0]=i+1;
zr[1]=j+1;
break;
}
}
}
returnz;
}
intWrong(LNode*Node)
intw=0,i,j;
board.pos[i][j]!
=goal[i][j]&
&
Node->
=0)
w++;
returnw;
intpick(LNode*Node)
intw=0,i,j,ii,jj;
=0){
for(ii=0;
ii<
ii++)
for(jj=0;
jj<
jj++)
if(Node->
board.pos[i][j]==goal[ii][jj]){
w=w+abs(ii-i)+abs(jj-j);
break;
}
LNode*extend(LNode*Node,intdepth,intzero[2],intmoveflag,intChoose)
LNode*NewNode=newLNode;
for(inti=0;
for(intj=0;
NewNode->
board.pos[i][j]=Node->
board.pos[i][j];
switch(moveflag)
{
case1:
//向左移,不能出界:
zero[1]>
=2
NewNode->
board.pos[zero[0]-1][zero[1]-1]=NewNode->
board.pos[zero[0]-1][zero[1]-2];
board.pos[zero[0]-1][zero[1]-2]=0;
case2:
//向右移,不能出界:
zero[1]<
board.pos[zero[0]-1][zero[1]];
board.pos[zero[0]-1][zero[1]]=0;
case3:
//向上移,不能出界:
zero[0]>
board.pos[zero[0]-2][zero[1]-1];
board.pos[zero[0]-2][zero[1]-1]=0;
case4:
//向下移,不能出界:
zero[0]<
board.pos[zero[0]][zero[1]-1];
board.pos[zero[0]][zero[1]-1]=0;
NewNode->
board.d=depth+1;
switch(Choose){
NewNode->
board.f=NewNode->
board.d+Wrong(NewNode);
break;
board.d+pick(NewNode);
}
board.move=moveflag;
parent=Node;
NodeQTY++;
returnNewNode;
voidInitList(LNode*&
Open,LNode*&
Close)
Open=(List)malloc(sizeof(LNode));
Close=(List)malloc(sizeof(LNode));
if(!
Open&
!
exit(Overflow);
Open->
next=NULL;
Close->
intListInsert(List&
L,LNode*NewNode)
Listp=L;
while(p->
next){
p=p->
next;
next=p->
p->
next=NewNode;
returntrue;
LNode*Getminf(List&
L)
{
Listp=L,q=L->
next,r=L,min;
min=q;
//p,q寻找f最小值的指针,r指向表L中min前一个元素
q)
returnNULL;
while(q)
if(min->
board.f>
q->
board.f){
r=p;
min=q;
p=q;
q=q->
r->
next=min->
min->
returnmin;
intmain()
inti,j,choose;
ListOpen,Close;
LNode*Best,*current;
LNode*Start=newLNode;
printf("
\t\t\t八数码问题求解\n"
);
\n请输入初始状态:
"
scanf("
%d"
&
(Start->
board.pos[i][j]));
(注:
Theflagofmovement--1:
左移;
2:
右移;
3:
上移;
4:
下移)\n"
初始棋盘状态:
\n"
printf("
|%d"
Start->
board.pos[i][j]);
printf("
|\n"
InitList(Open,Close);
请选择(1:
A算法;
A*算法):
scanf("
choose);
Start->
board.d=0;
switch(choose){
Start->
board.f=Start->
board.d+Wrong(Start);
board.d+pick(Start);
}//Start->
board.f=0+Wrong(Start);
Start->
board.move=0;
parent=NULL;
flag=1;
ListInsert(Open,Start);
//将S加入到Open表中
while(Open->
Best=Getminf(Open);
ListInsert(Close,Best);
if(!
(Best->
board.f-Best->
board.d)){
$$$******有解!
******$$$\n"
break;
z=Findzero(Best);
zero[0]=*(z+0);
zero[1]=*(z+1);
if(zero[1]>
=N-1&
Best->
board.move!
=2)
ListInsert(Open,extend(Best,Best->
board.d,zero,1,choose));
if(zero[1]<
=1)
ListInsert(Open,extend(Be