TYVJ 1541&&洛谷P379 八数码问题

一个比较经典的题,相信小伙伴们都玩过九宫格八个块的拼图游戏,这道题可以看成是这个游戏的抽象化,每个拼图块抽象成一个数字,求还原拼图,即将9个数字复位的最小步数,这道题给的初始状态,即要还原的状态是“123/804/765”,我在这里先讲最简单的一个算法IDA*,看到网上大佬们用双向搜hash判重,set判重等等等等,身为小蒟蒻的我,瑟瑟发抖,然而我这道题IDA*完美水过,下面讲思路

第一步,准备,一个map二位数组存图,一个mmp数组用来每次搜索,now数组表示0~8的数字所在的位置,这里的位置是1~9,然后是hope数组,预处理好,hope里存的是每个数字应该在的位置,然后是dis数组,存的是每两个点之间换过去需要的步数,还有两个方向数组,dfs扩展用

第二步,读入,先读入一个字符串,定义一个cnt=0,下面两重循环,每层3位,模拟九宫格,用cnt来循环字符串,cnt+1即为当前位的数字的now,即当前位置(1~9),然后如果当前的数字是零,那么用一个stx,sty存储它对应的i,j,因为我们要从空格子开始移动

第三步,IDA*,lim限制深度不用说,每次进IDA*之前,将map数组memcpy到mmp中,用mmp来模拟交换,传参传三个,当前深度,当前点横纵坐标,然后模拟当前点与他的上下左右交换

第四步,剪枝,用一个fuck=0,加上每个点当前位置到他的hope位置的dis值,如果当前IDA*的deep加上fuck>lim,那么当前搜索无解,return ,如果fuck=0,那么所有点回到了原位,return 1;

代码

By Acer.Mo
#include
#include
#include
#include
#include
#include
using namespace std;
int map[5][5],mmp[5][5];//两个地图 
int lim,stx,sty,cnt=0;
int dis[10][10]=
{
	{0,0,0},
	{0,0,1,2,1,2,3,2,3,4},
	{0,1,0,1,2,1,2,3,2,3},
	{0,2,1,0,3,2,1,4,3,2},
	{0,1,2,3,0,1,2,1,2,3},
	{0,2,1,2,1,0,1,2,1,2},
	{0,3,2,1,2,1,0,3,2,1},
	{0,2,3,4,1,2,3,0,1,2},
	{0,3,2,3,2,1,2,1,0,1},
	{0,4,3,2,3,2,1,2,1,0}
};//预处理的dis 
int fx[5]={0,0,1,-1},fy[5]={1,-1,0,0};
int now[10],hope[10]={5,1,2,3,6,9,8,7,4};//期望位置与当前位置 
int cutdown()  
{
	int fuck=0;
	for(int i=1;i<=8;i++) fuck+=dis[now[i]][hope[i]];
	return fuck;
}//剪枝 
int IDAS(int limdep,int sx,int sy)
{
	if (limdep+cutdown()>lim) return 0;
	if (cutdown()==0) return 1;
	for (int i=0;i<4;i++)
	{
		int xx=sx+fx[i];
		int yy=sy+fy[i];
		if (xx>3||yy>3||xx<1||yy<1) continue;
		swap(mmp[xx][yy],mmp[sx][sy]);//交换两个块地图中的位置 
		swap(now[mmp[xx][yy]],now[mmp[sx][sy]]);//下标位置 
		if (IDAS(limdep+1,xx,yy)) return 1;
		swap(mmp[xx][yy],mmp[sx][sy]);//回溯 
		swap(now[mmp[xx][yy]],now[mmp[sx][sy]]);//同理 
	}
	return 0;
}
int main()
{
	string s;
	cin>>s;
	for (int i=1;i<=3;i++)
	{
		for (int k=1;k<=3;k++)
		{
			map[i][k]=s[cnt++]-'0';
			now[map[i][k]]=cnt;//cnt循环字符串下标 
			if (map[i][k]==0) stx=i,sty=k;//起点坐标 
		}
	}
	for (lim=0;;lim++)
	{
		memcpy(mmp,map,sizeof(map));
		if (IDAS(0,stx,sty)) break;
	} //IDA* 
	printf("%d",lim);
	return 0;
}

小伙伴的双向搜索+hashhttps://blog.csdn.net/qq_41570588/article/details/79921976

 

你可能感兴趣的:(爆搜)