64,648
社区成员
发帖
与我相关
我的任务
分享
#include<iostream.h>
#include<stdio.h>
#include<stdlib.h>
#define MAX 50000
struct shumanode
{
char a[9];//状态
int b;//父节点
int c;//存放权值(与目标节点的不同点数)
int d;//空格的位置
int e;//存放节点编号
int f;//指示是否访问过,1表示访问过
};
struct shumanode search();
int panduanyoujie();
void readdata();
void init();
struct shumanode takeoutofopen();
int notused(struct shumanode v);
void addtoopen(struct shumanode v);
int isaim(struct shumanode v);
int canturntoright(struct shumanode u) ;
int canturntoleft(struct shumanode u);
int canturntoshang(struct shumanode u);
int canturntoxia(struct shumanode u);
struct shumanode turntoshang(struct shumanode u);
struct shumanode turntoxia(struct shumanode u);
struct shumanode turntoleft(struct shumanode u);
struct shumanode turntoright(struct shumanode u);
void print();
struct shumanode open[MAX];
struct shumanode s,t;//
int head,tail,openlen=20000;
int num=-1;
struct shumanode m;
int main()
{
int c;
readdata();
init();
c=panduanyoujie();
if(c==1)
{
m=search();
print();
}
else cout<<"无解!"<<endl;
return 0;
}
struct shumanode search() //广搜返回目标结点的最小步数
{
struct shumanode u,v;
while(1)
{
u=takeoutofopen();
if(isaim(u)) //判是否是目标结点
return(u);
if(canturntoshang(u))
{
v=turntoshang(u);
if(notused(v)) //如果该结点是合法的结点(未越界且是空格)
addtoopen(v); //加入到open表
}
if(canturntoright(u))
{
v=turntoright(u);
if(notused(v)) //如果该结点是合法的结点(未越界且是空格)
addtoopen(v); //加入到open表
}
if(canturntoleft(u))
{
v=turntoleft(u);
if(notused(v)) //如果该结点是合法的结点(未越界且是空格)
addtoopen(v); //加入到open表
}
if(canturntoxia(u))
{
v=turntoxia(u);
if(notused(v)) //如果该结点是合法的结点(未越界且是空格)
addtoopen(v); //加入到open表
}
}
}
//判断该结点是否是到达过的结点,1表示该节点不存在
int notused(struct shumanode v)
{
int flag=1;
int sum=0;//flag=0表示该节点存在,
for(int i=head;i<tail;i++)
{
for(int j=0;j<9;j++)
if(open[i].a[j]==v.a[j])
sum++;
if(sum==9)
{
flag=0;//u,v相同,该节点存在
return 0;
}
sum=0;
}
return 1;
}
void addtoopen(struct shumanode v) //加入到open表
{
num++;
v.e=num;
open[tail++]=v;
if(tail>MAX)
{
cout<<"空间不足!"<<endl;
exit(0);
}
}
struct shumanode takeoutofopen() //从open表中取出未用的,并且权值最小的结点
{
int min=100;
int i,j;
for(i=head;i<tail;i++)
if(open[i].c<min&&open[i].f==0)
{
min=open[i].c;j=i;
}
open[j].f=1;
return open[j];
}
void init() //初始化
{
head=0;
tail=0;
if(isaim(s))
{
cout<<"起始节点就是目标节点"<<endl;
exit(0);
}
addtoopen(s); //把起始点加入到open表
}
void readdata() //读入数据
{
char c;
for(int i=0;i<9;i++)
scanf("%c%c",&s.a[i],&c);
s.b=-1;//父节点
s.c=0;//存放权值(与目标节点的不同点数
s.e=0;
s.f=0;
for(i=0;i<9;i++)
scanf("%c%c",&t.a[i],&c);
for(i=0;i<9;i++)
{
if(s.a[i]==' ')
s.d=i;
if(s.a[i]!=t.a[i])
s.c++;
}
}
int isaim(struct shumanode v) //判断该结点是否是目标结点
{
if(v.c==t.c)
return 1;
else
return 0;
}
int canturntoright(struct shumanode u) //u能向右移动
{
int i,j;
i=u.d/3;
j=u.d%3;
if(j<2) return 1;
else return 0;
}
struct shumanode turntoright(struct shumanode u) //u向右得到新结点v
{
struct shumanode v;
int i,j;
i=u.d/3;
j=u.d%3;
v=u;
v.a[v.d]=v.a[v.d+1];
v.a[v.d+1]=' ';
v.d++;
v.b=u.e;
v.e=num;
v.c=0;
v.f=0;
for(i=0;i<9;i++)
if(v.a[i]!=t.a[i])
v.c++;
return(v);
}
int canturntoleft(struct shumanode u) //u能向左移动
{
int i,j;
i=u.d/3;
j=u.d%3;
if(j>0) return 1;
else return 0;
}
struct shumanode turntoleft(struct shumanode u) //u向左得到新结点v
{
struct shumanode v;
int i,j;
i=u.d/3;
j=u.d%3;
v=u;
v.a[v.d]=v.a[v.d-1];
v.a[v.d-1]=' ';
v.d--;
v.b=u.e;
v.e=num;
v.f=0;
v.c=0;
for(i=0;i<9;i++)
if(v.a[i]!=t.a[i])
v.c++;
return(v);
}
int canturntoshang(struct shumanode u) //u能向上移动
{
int i,j;
i=u.d/3;
j=u.d%3;
if(i>0) return 1;
else return 0;
}
struct shumanode turntoshang(struct shumanode u) //u向上得到新结点v
{
struct shumanode v;
int i,j;
i=u.d/3;
j=u.d%3;
v=u;
v.a[v.d]=v.a[v.d-3];
v.a[v.d-3]=' ';
v.d=v.d-3;
v.b=u.e;
v.e=num;
v.c=0;
v.f=0;
for(i=0;i<9;i++)
if(v.a[i]!=t.a[i])
v.c++;
return(v);
}
int canturntoxia(struct shumanode u) //u能向下移动
{
int i,j;
i=u.d/3;
j=u.d%3;
if(i<2) return 1;
else return 0;
}
struct shumanode turntoxia(struct shumanode u) //u向下得到新结点v
{
struct shumanode v;
int i,j;
i=u.d/3;
j=u.d%3;
v=u;
v.a[v.d]=v.a[v.d+3];
v.a[v.d+3]=' ';
v.d=v.d+3;
v.b=u.e;
v.e=num;
v.f=0;
v.c=0;
for(i=0;i<9;i++)
if(v.a[i]!=t.a[i])
v.c++;
return(v);
}
void print()
{
struct shumanode v;
int a[10000],i=0;
int M=1;
v=m;
do{
a[i++]=v.e;
for(int j=head;j<tail;j++)
if(v.b==open[j].e)
v=open[j];
}
while(v.b!=-1);
cout<<"共需"<<i<<"步"<<endl;
for(int j=i-1;j>=0;j--)
{ cout<<"第"<<M++<<"步"<<endl;
for(int k=0;k<9;k++)
{
printf("%c ",open[a[j]].a[k]);
if((k+1)%3==0)
cout<<endl;
}
}
}
int panduanyoujie()
{
int sum1=0,sum2=0;
for(int i=0;i<9;i++)
for(int j=0;j<i;j++)
if(s.a[i]!=' '&&s.a[j]!=' '&&s.a[j]>s.a[i])
sum1++;
for(i=0;i<9;i++)
for(int j=0;j<i;j++)
if(t.a[i]!=' '&&t.a[j]!=' '&&t.a[j]>t.a[i])
sum2++;
if(sum1%2==sum2%2)
return 1;
else return 0;
}