【题目描述】
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
【输入描述】
输入初试状态,一行九个数字,空格用0表示。
【输出描述】
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)。
【样例输入】
283104765
【样例输出】
4
IDA*算法:
源代码: #include<cstdio> #include<algorithm> using namespace std; int Goal[3][3]={{1,2,3}, {8,0,4}, {7,6,5}}; int x[4]={1,-1,0,0},y[4]={0,0,-1,1}; int X,Y,K,i[3][3]; bool Flag(0); bool Check() { for (int a=0;a<3;a++) for (int b=0;b<3;b++) if (i[a][b]!=Goal[a][b]) return false; return true; } bool Eva(int t,int i[3][3]) { int num(0); for (int a=0;a<3;a++) for (int b=0;b<3;b++) if (i[a][b]!=Goal[a][b]) { num++; if (num+t>K) return false; } return true; } void Solve(int t,int i[3][3],int X,int Y,int xxx,int yyy) { if (t==K) { if (Check()) Flag=true; return; } if (Flag) return; for (int a=0;a<4;a++) { int t1=X+x[a],t2=Y+y[a]; if (t1<0||t1>2||t2<0||t2>2||(t1==xxx&&t2==yyy)) continue; swap(i[X][Y],i[t1][t2]); if (Eva(t,i)) Solve(t+1,i,t1,t2,X,Y); swap(i[X][Y],i[t1][t2]); } } int main() { for (int a=0;a<3;a++) for (int b=0;b<3;b++) { char t; scanf("%c",&t); i[a][b]=t-'0'; if (!i[a][b]) { X=a; Y=b; } } while (!Flag) { K++; Solve(0,i,X,Y,X,Y); } printf("%d",K); return 0; }
双向广搜: