在3×3的棋盘上,摆有八个棋子,每一个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子能够移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。ios
输入初试状态,一行九个数字,空格用0表示布局
输出格式:只有一行,该行只有一个数字,表示从初始状态到目标状态须要的最少移动次数(测试数据中无特殊没法到达目标状态数据)测试
283104765
4
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~spa
bfs+hash+字符串~code
每次搜出0的位置,而后dfs搜索移动位置,只要搜出解,马上输出便可。ci
字符串的操做超神奇,刷新认知啊~字符串
(CSDN竟然不能给本身点赞了,差评。)string
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int ha,ta,num[1000001],k,now,tim,cnt,fi[1000001],ne[1000001]; string n,q[10000001],fin[10]={"13","240","51","046","1573","284","37","486","57"},tmp,kkz,cun[1000001]; bool findd(string s) { int tot=0;int siz=s.size(); for(int i=0;i<siz;i++) tot=tot*33+s[i]-'0'; tot%=1000007; for(int i=fi[tot];i;i=ne[i]) if(cun[i]==s) return 0; cun[++cnt]=s;ne[cnt]=fi[tot];fi[tot]=cnt; } int main() { cin>>n; if(n=="123804765") { printf("0\n");return 0; } q[1]=n;num[1]=0;ta=1; while(ha!=ta) { tmp=q[++ha];tim=num[ha];k=tmp.find("0",0); for(int i=0;i<fin[k].size();i++) { kkz=tmp;now=fin[k][i]-'0'; swap(kkz[now],kkz[k]); if(kkz=="123804765") { printf("%d\n",tim+1);return 0; } if(findd(kkz)) q[++ta]=kkz,num[ta]=tim+1; } } return 0; }