codevs1225 八数码难题
题目描述 Description
Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.
问题描述
在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。
输入描述 Input Description
输入初试状态,一行九个数字,空格用0表示
输出描述 Output Description
只有一行,该行只有一个数字,表示从初始状态到目标状态需要的最少移动次数(测试数据中无特殊无法到达目标状态数据)
样例输入 Sample Input
283104765
样例输出 Sample Output
4
#include<bits/stdc++.h> using namespace std; struct situation{int s,step;}; int a[4][4],t=123804765; map<int,bool> use; queue<situation> q; int bfs(int now){ q.push((situation){now,0}); while(!q.empty()){ situation u=q.front(); q.pop(); int x=u.s,st=u.step,x1,y1; if(x==t)return st; for(int i=3;i>0;i--) for(int j=3;j>0;j--){ a[i][j]=x%10; x/=10; if(!a[i][j]){x1=i; y1=j;} } if(x1>1){ swap(a[x1][y1],a[x1-1][y1]); x=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++)x=x*10+a[i][j]; if(!use[x]){q.push((situation){x,st+1}); use[x]=1;} swap(a[x1][y1],a[x1-1][y1]); } if(x1<3){ swap(a[x1][y1],a[x1+1][y1]); x=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++)x=x*10+a[i][j]; if(!use[x]){q.push((situation){x,st+1}); use[x]=1;} swap(a[x1][y1],a[x1+1][y1]); } if(y1>1){ swap(a[x1][y1],a[x1][y1-1]); x=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++)x=x*10+a[i][j]; if(!use[x]){q.push((situation){x,st+1}); use[x]=1;} swap(a[x1][y1],a[x1][y1-1]); } if(y1<3){ swap(a[x1][y1],a[x1][y1+1]); x=0; for(int i=1;i<=3;i++) for(int j=1;j<=3;j++)x=x*10+a[i][j]; if(!use[x]){q.push((situation){x,st+1}); use[x]=1;} swap(a[x1][y1],a[x1][y1+1]); } } } int main(){ int x; cin>>x; cout<<bfs(x)<<endl; return 0; }