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;
}

浙公网安备 33010602011771号