經典的寬搜題目,感覺最好的辦法應該是雙向廣搜。
不過用簡單的啟發式搜索可以飄過。
#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; }