bfs,像输入一样我们用一个数来表示状态,因为不能开一个9位的数组,又因为如果数的八位确定,那么最后一位就能确定,所以我们可以开一个8位的数组来记录这个状态是否进过队。
重点是将0与其它位转换,基于九宫格的特点,我们只能将0与和它相距 1 -1 3 -3 位的数字交换,下面是数位交换的原则:
1. 要得到第x位前面的部分:/10^x
2. 要得到第x位后面的部分:%10^(x-1)
3. 要得到第x位的部分:/10^(x-1) %10
还需要注意一个问题(一开始自己忽略掉了),就是0在九宫格的最右边是不能与下一位的数交换,同理在最左边时,也不能与上一位的数字交换。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<vector>
#include<queue>
#define T 123804765
using namespace std;
int ans,s;
bool f[88888888];
int MOD[]={1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000};//MOD[i]是10^i
struct H{
int x,step;
};
int mov[]={-1,1,-3,3};//0的移动方向:左右上下
int bfs()
{
queue <H> q;
H k;
k.x=s;k.step=0;
f[s/10]=1;
q.push(k);
while(!q.empty())
{
k=q.front();
q.pop();
if(k.x==T) return k.step;
int j=1,p=k.x;
while(p%10)
{j++;p/=10;}//第几位是0
for(int i=0;i<4;i++)
{
int t=j,tt=j+mov[i];//0要交换到的位
if(t%3==0&&mov[i]==1) continue;
if(t%3==1&&mov[i]==-1) continue;
if(tt>=1&&tt<=9)
{
if(t<tt) swap(t,tt);
int x;
x=k.x/MOD[t]*MOD[t]+k.x%MOD[tt-1];
int x1=k.x/MOD[t-1]%10;
int x2=k.x/MOD[tt-1]%10;
int x3=((k.x/MOD[tt]*MOD[tt])%MOD[t-1]);
x+=x3+x1*MOD[tt-1]+x2*MOD[t-1];
if(!f[x/10])
{
H l;
if(x==T) return k.step+1;
l.x=x,l.step=k.step+1;
q.push(l);f[x/10]=1;
}
}
}
}
}
int main()
{
scanf("%d",&s);
ans=bfs();
printf("%d",ans);
return 0;
}