描述:
在九宫格里放在1到8共8个数字还有一个是空格,与空格相邻的数字可以移动到空格的位置,问给定的状态最少需要几步能到达目标状态(用0表示空格):
1 2 3
4 5 6
7 8 0
输入:
输入一个给定的状态。
输出:
输出到达目标状态的最小步数。不能到达时输出-1。
输入样例:
1 2 3 4 0 6 7 5 8
输出样例:
2
#include<iostream>
#include<map>
#include<queue>
using namespace std;
#include<map>
#include<queue>
using namespace std;
void readdate(); //读入数据
void init(); //初始化
int bfs();
int canmoveto(int u,int i);
int moveto(int u,int i);
void init(); //初始化
int bfs();
int canmoveto(int u,int i);
int moveto(int u,int i);
map<int, int>smap; //记录步数和标记是否是已到达的结点。
queue<int>q1;
int bs[3][3],a[3][3];
int isdate;
//0, 1, 2, 3分别表示左下右上的方向,dr表示行的偏移量,dc表示列的偏移量。
int dr[4]={0, 1, 0, -1};
int dc[4]={-1, 0, 1, 0};
queue<int>q1;
int bs[3][3],a[3][3];
int isdate;
//0, 1, 2, 3分别表示左下右上的方向,dr表示行的偏移量,dc表示列的偏移量。
int dr[4]={0, 1, 0, -1};
int dc[4]={-1, 0, 1, 0};
int main()
{
int num;
readdate();
init();
num=bfs();
cout<<num<<endl;
return 0;
}
{
int num;
readdate();
init();
num=bfs();
cout<<num<<endl;
return 0;
}
void readdate()
{
int i,j,num=0;
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
cin>>bs[i][j];
num=num*10+bs[i][j];//用num表示数组,后面好判断,防止数组过大。
}
}
isdate=num;
}
void init()
{
q1.push(isdate);//初始化把初始坐标放入数据。
smap[isdate]=0; //表示为第0步。
}
int bfs()
{
int u,v,i;
while(!q1.empty())
{
u=q1.front();
q1.pop();
for(i=0; i<4; i++)
{
if(canmoveto(u,i))//判断是否为合法的结点,不会下标越界。
{
v=moveto(u,i);
//判断v是否与目标相等。
if(v==123456780)
{
return smap[u]+1;
}
if(smap.count(v)==0)//v是否是已经到达的状态,等于0表示没用过。
{
q1.push(v);
smap[v]=smap[u]+1;
}
}
}
}
return -1;//如果无解就返回-1;
}
{
int i,j,num=0;
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
cin>>bs[i][j];
num=num*10+bs[i][j];//用num表示数组,后面好判断,防止数组过大。
}
}
isdate=num;
}
void init()
{
q1.push(isdate);//初始化把初始坐标放入数据。
smap[isdate]=0; //表示为第0步。
}
int bfs()
{
int u,v,i;
while(!q1.empty())
{
u=q1.front();
q1.pop();
for(i=0; i<4; i++)
{
if(canmoveto(u,i))//判断是否为合法的结点,不会下标越界。
{
v=moveto(u,i);
//判断v是否与目标相等。
if(v==123456780)
{
return smap[u]+1;
}
if(smap.count(v)==0)//v是否是已经到达的状态,等于0表示没用过。
{
q1.push(v);
smap[v]=smap[u]+1;
}
}
}
}
return -1;//如果无解就返回-1;
}
int canmoveto(int u,int tmp)
{
int brow,bcol;
int i,j,flag=1;
for(i=2; i>=0&&flag==1; i--)
{
for(j=2; j>=0; j--)
{
a[i][j]=u%10;
u=u/10;
if(a[i][j]==0)
{
brow=i;
bcol=j;
flag=0;
break;
}
}
}
brow=brow+dr[tmp];
bcol=bcol+dc[tmp];
if(brow>=0&&brow<3&&bcol>=0&&bcol<3)//如果可以到达下一个节点,就返回1;
{
return 1;
}
return 0; //不可以到达返回0
}
int moveto(int u,int tmp)
{
int i,j;
int brow,bcol;
int r,c;
int v=0;
for(i=2; i>=0; i--)
{
for(j=2; j>=0; j--)
{
bs[i][j]=u%10;
u=u/10;
if(bs[i][j]==0)
{
brow=i;
bcol=j;
}
}
}
r=brow+dr[tmp];
c=bcol+dc[tmp];
bs[brow][bcol]=bs[r][c];
bs[r][c]=0;
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
v=v*10+bs[i][j];
}
}
return v; //移动后到达的新状态。
}
{
int brow,bcol;
int i,j,flag=1;
for(i=2; i>=0&&flag==1; i--)
{
for(j=2; j>=0; j--)
{
a[i][j]=u%10;
u=u/10;
if(a[i][j]==0)
{
brow=i;
bcol=j;
flag=0;
break;
}
}
}
brow=brow+dr[tmp];
bcol=bcol+dc[tmp];
if(brow>=0&&brow<3&&bcol>=0&&bcol<3)//如果可以到达下一个节点,就返回1;
{
return 1;
}
return 0; //不可以到达返回0
}
int moveto(int u,int tmp)
{
int i,j;
int brow,bcol;
int r,c;
int v=0;
for(i=2; i>=0; i--)
{
for(j=2; j>=0; j--)
{
bs[i][j]=u%10;
u=u/10;
if(bs[i][j]==0)
{
brow=i;
bcol=j;
}
}
}
r=brow+dr[tmp];
c=bcol+dc[tmp];
bs[brow][bcol]=bs[r][c];
bs[r][c]=0;
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
{
v=v*10+bs[i][j];
}
}
return v; //移动后到达的新状态。
}