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;
}
posted @ 2017-06-22 18:40  wqtnb_tql_qwq_%%%  阅读(214)  评论(0编辑  收藏  举报