经典的宽搜题目,感觉最好的办法应该是双向广搜。
不过用简单的启发式搜索可以飘过。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
int a,b;
char ans[1111111][7];
int inf[7]={1,1,10,100,1000,10000,100000};
struct D
{
int key;
char x,sum,now;
bool operator <(const struct D & xx) const
{
if(sum==xx.sum)
return now<xx.now;
return sum>xx.sum;
}
};
priority_queue <D> q;
int cal(int key,int x,int b)
{
int from[7],to[7];
for(int i=1;i<=6;i++)
{
from[i]=key%10;
key/=10;
to[i]=b%10;
b/=10;
}
int ret=0;
for(int i=1;i<=6;i++)
if(i!=x)
{
ret+=from[i]!=to[i];
}
sort(from+1,from+1+6);
sort(to+1,to+1+6);
for(int i=1;i<=6;i++)
{
if(from[i]-to[i]>0)
ret+=from[i]-to[i];
else
ret+=to[i]-from[i];
}
return ret;
}
int bfs(int a,int b)
{
memset(ans,100,sizeof(ans));
ans[a][1]=0;
struct D xx;
xx.key=a;
xx.sum=0+cal(a,1,b);
xx.x=1;
xx.now=0;
q.push(xx);
while(1)
{
int key=q.top().key;
int x=q.top().x;
int tmp=ans[key][x];
q.pop();
if(key==b)
return tmp;
if(x<6&&tmp+1<ans[key][x+1])
{
xx.now=ans[key][x+1]=tmp+1;
xx.key=key;
xx.x=x+1;
xx.sum=tmp+cal(key,x+1,b);
q.push(xx);
}
int txt=inf[6-x+1];
int keyx=key/txt%10;
if(keyx>0&&tmp+1<ans[key-1*txt][x])
{
xx.now=ans[key-1*txt][x]=tmp+1;
xx.key=key-1*txt;
xx.x=x;
xx.sum=tmp+cal(key-1*txt,x,b);
q.push(xx);
}
if(keyx<9&&tmp+1<ans[key+1*txt][x])
{
xx.now=ans[key+1*txt][x]=tmp+1;
xx.key=key+1*txt;
xx.x=x;
xx.sum=tmp+cal(key+1*txt,x,b);
q.push(xx);
}
int tt=key/inf[6];
int to=key%inf[6]+keyx*inf[6]-keyx*txt+tt*txt;
if(tmp+1<ans[to][x])
{
xx.now=ans[to][x]=tmp+1;
xx.key=to;
xx.x=x;
xx.sum=tmp+cal(to,x,b);
q.push(xx);
}
tt=key%10;
to=key/10*10+keyx-keyx*txt+tt*txt;
if(tmp+1<ans[to][x])
{
xx.now=ans[to][x]=tmp+1;
xx.key=to;
xx.x=x;
xx.sum=tmp+cal(to,x,b);
q.push(xx);
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d %d",&a,&b);
int ans=bfs(a,b);
cout<<ans<<endl;
return 0;
}