1571.八数码
时限:5000ms 内存限制:20000K 总时限:10000ms
描述
在九宫格里放在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<cstdio>
#include<cstring>
#include<queue>
#include<map>
using namespace std;
map<int,int>shape;
int a[3][3];
int b[3][3];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
queue<int>q;
int canmoveto(int x,int k)
{
int flag=0;
int tx,ty,i,j;
for(i=2;i>=0;i--)
{
for(j=2;j>=0;j--)
{
b[i][j]=x%10;
if(b[i][j]==0)
{
flag=1;
break;
}
x=x/10;
}
if(flag==1)break;
}
tx=i+dir[k][0];
ty=j+dir[k][1];
if(tx>=3||ty>=3||tx<0||ty<0)
{
return 0;
}
else return 1;
}
int moveto(int x,int k)
{
int tx,ty,i,j;
int row;int col;
int sum2=0;
for(i=2;i>=0;i--)
{
for(j=2;j>=0;j--)
{
b[i][j]=x%10;
{
if(b[i][j]==0)
{
row=i;
col=j;
}
}
x=x/10;
}
}
tx=row+dir[k][0];
ty=col+dir[k][1];
b[row][col]=b[tx][ty];
b[tx][ty]=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
sum2=sum2*10+b[i][j];
}
return sum2;
}
int bfs()
{
int x,y;
while(!q.empty())
{
x=q.front();
q.pop();
if(x==123456780)return shape[x];
for(int i=0;i<4;i++)
{
if(canmoveto(x,i))
{
y=moveto(x,i);
if(y==123456780)return shape[x]+1;
else
{
if(shape.count(y)==0)
{
shape[y]=shape[x]+1;
q.push(y);
}
}
}
}
}
return -1;
}
int main()
{
int sum1=0;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
{
cin>>a[i][j];
sum1=sum1*10+a[i][j];
}
q.push(sum1);
shape[sum1]=0;
cout<<bfs()<<endl;
return 0;
}