BFS特训:八数码问题

解题思路:因为题目要求求解最小的步数,自然而然想到应用BFS,状态是一目了然的,即是整个表格的排布。我这里刚开始使用三维数组存放整个表格,方块移动通过交换数组元素很容易实现,但是判断是否已经处理过相同状态时需要判断每一个元素,显得比较笨拙,可以将数组元素转化为整数丢入set中判重,能够提高一定的效率。最好是能利用哈希表映射查询,能够取得比较好的效果。

题目大意:在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字。棋盘中留有一个空格,空格用0来表示。空格周围的棋子可以移到空格中。要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找到一种最少步骤的移动方法,实现从初始布局到目标布局的转变。

 

BFS特训:八数码问题_第1张图片

#include
#include
#include
#include
#include
#include
using namespace std;

struct maze{
	int x,y;      //0的位置
	int a[3][3]; 
	bool operator <(const maze &A) const
	{
		int tmp=memcmp(a,A.a,sizeof(a));
		if(tmp!=0)return tmp<0;
		else if(x!=A.x)return x Q;
queue time;
set A;


int BFS()
{
	while(Q.empty()==false)
	{
		
		maze tmp=Q.front(); Q.pop();
		int t=time.front();time.pop();
		for(int i=0;i<4;i++)
		{
			maze tmp2;
			tmp2.x=tmp.x+go[i][0];
			tmp2.y=tmp.y+go[i][1];
			if(tmp2.x<0||tmp2.x>=3||tmp2.y<0||tmp2.y>=3) continue;
			memcpy(tmp2.a,tmp.a,sizeof(tmp.a));
			swap(tmp2.a[tmp.x][tmp.y],tmp2.a[tmp2.x][tmp2.y]);
			if(A.count(tmp2)) continue;
			if(memcmp(tmp2.a,end.a,sizeof(end.a))==0) return t+1;
			Q.push(tmp2);
			time.push(t+1);
			A.insert(tmp2);
		}
	}
	return -1;
}

int main()
{
	while(1)
	{
		for(int i=0;i<3;i++)
		{
			for(int j=0;j<3;j++)
			{
				scanf("%d",&begin.a[i][j]);
				if(begin.a[i][j]==0)
				{
					begin.x=i;
					begin.y=j;
				}
			}
		}
		for(int i=0;i<3;i++)
		{
			for(int j=0;j<3;j++)
			{
				scanf("%d",&end.a[i][j]);
				if(end.a[i][j]==0)
				{
					end.x=i;
					end.y=j;
				}
			}
		}
		Q.push(begin);
		time.push(0);
		A.insert(begin);
		int ans=BFS();
		printf("%d\n",ans);
	}
	return 0;
}

 

你可能感兴趣的:(BFS特训:八数码问题)