八数码难题
题目描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入输出格式
输入格式:
输入初试状态,一行九个数字,空格用0表示
输出格式:
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
输入输出样例
输入样例#1:
283104765
输出样例#1:
4
代码实现:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<map> 5 using namespace std; 6 map <string,int>v; 7 map <string,int>step; 8 int a,b,t,head=0,tail=0; 9 int bh[]={-3,-1,1,3},wz[100000],tou[100000]; 10 string s,rs("123804765"),dl[100000],ns; 11 int main(){ 12 cin>>s; 13 a=s.find('0');//a是‘0’的位置。 14 wz[head]=a; 15 tou[head]=1; 16 dl[head++]=s; 17 wz[head]=4; 18 tou[head]=2; 19 dl[head++]=rs; 20 v[s]=1; 21 while(tail<=head){ 22 a=wz[tail]; 23 t=tou[tail]; 24 s=dl[tail++]; 25 b=step[s]; 26 for(int i=0;i<4;i++){ 27 ns=s; 28 if(i==0&&a>2){ 29 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a]; 30 } 31 if(i==1&&a!=0&&a!=3&&a!=6){ 32 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a]; 33 } 34 if(i==2&&a!=2&&a!=5&&a!=8){ 35 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a]; 36 } 37 if(i==3&&a<6){ 38 ns[a]=s[a+bh[i]];ns[a+bh[i]]=s[a]; 39 } 40 if(v[ns]!=t){ 41 if(!v[ns]){ 42 v[ns]=t;wz[head]=a+bh[i];tou[head]=t; 43 dl[head++]=ns;step[ns]=b+1; 44 } 45 else{cout<<b+1+step[ns]<<endl;return 0;} 46 } 47 } 48 } 49 return 0; 50 }
很久之前的代码了,我其实也不知道现在能不能打出来。(现在敲应该也就30+吧,这是病。)
题目来源:CODE[VS]