/*
八数码问题之stl:
1set<State> vis,这样只需要调用if(vis.count(s))来判断s是否在集合vis中,并用vis.insert(s)加入集合,用vis.remove(s)从集合中移除s。
问题:并不是所有类型的State都可以作为set中的元素类型。set的元素必须定义"<"运算符,C语言原生的数组(包括字符数组)却不行。
2如果数组不能转化为整数,自己声明结构体,重载函数调用符比较状态。下面中,整数a和b分别是两个状态在状态数组st中的下标,在比较时直接使用memcpy来比较整个
内存块
输入:
2 6 4 1 3 7 0 5 8
8 1 5 7 3 6 4 0 2
输出:
31
*/
/*
关键:
1set<State> vis,这样只需要调用if(vis.count(s))来判断s是否在集合vis中,并用vis.insert(s)加入集合,用vis.remove(s)从集合中移除s。
问题:并不是所有类型的State都可以作为set中的元素类型。set的元素必须定义"<"运算符,C语言原生的数组(包括字符数组)却不行。
2如果数组不能转化为整数,自己声明结构体,重载函数调用符比较状态。下面中,整数a和b分别是两个状态在状态数组st中的下标,在比较时直接使用memcpy来比较整个
内存块。
typedef struct Cmp
{
bool operator()(int iIndexA,int iIndexB) const//注意,容器中的比较函数用的是重载函数调用操作符,本质上仍然是比较操作
3 int memcmp(const void* buf1,const void* buf2,size_t count)
*/
#include <stdio.h>
#include <string.h>
#include <set>
using namespace std;
#define MAXSIZE 1000000
typedef int State[9];
State st[MAXSIZE],stEnd;
int iDist[MAXSIZE];
set<int> setState;//这里穿入的是哈希值
int go[][2] =
{
-1,0,
1,0,
0,-1,
0,1
};
typedef struct Cmp
{
bool operator()(int iIndexA,int iIndexB) const//注意,容器中的比较函数用的是重载函数调用操作符,本质上仍然是比较操作
{
return memcmp(&st[iIndexA],&st[iIndexB],sizeof(st[iIndexB])) < 0 ;
}
}Cmp;
set<int,Cmp> setState2;
void init2()
{
setState2.clear();
}
bool isInsert2(int iIndex)
{
if(setState2.count(iIndex))
{
return false;
}
else
{
setState2.insert(iIndex);
return true;
}
}
void init()
{
setState.clear();
}
bool isInsert(int iNum)
{
int iSum = 0;
for(int i = 0 ; i < 9; i++)
{
iSum = iSum * 10 + st[iNum][i];
}
if(setState.count(iSum))
{
return false;
}
else
{
setState.insert(iSum);
return true;
}
}
int bfs()
{
int iFront = 1,iRear = 2;
init2();
while(iFront < iRear)
{
State& state = st[iFront];
if(memcmp(stEnd,state,sizeof(state)) == 0)
{
return iFront;
}
int iX,iY,iZ;
for(iZ = 0; iZ < 9 ; iZ++)
{
if(!state[iZ])//这里不是st[iZ]
{
break;
}
}
iX = iZ / 3;
iY = iZ % 3;
for(int i = 0 ; i < 4 ; i++)
{
int iNewX = iX + go[i][0];
int iNewY = iY + go[i][1];
int iNewZ = iNewX * 3 + iNewY;
if(iNewX < 3 && iNewX >= 0 && iNewY < 3 && iNewY >= 0)
{
State& newState = st[iRear];
//memcpy(newState,state,sizeof(state));
memcpy(&newState,&state,sizeof(state));
newState[iNewZ] = state[iZ];
newState[iZ] = state[iNewZ];
iDist[iRear] = iDist[iFront] + 1;
if(isInsert2(iRear))
{
iRear++;
}
}
}
iFront++;
}
return -1;
}
void process()
{
iDist[1] = 0;
for(int i = 0 ; i < 9; i++)
{
scanf("%d",&st[1][i]);
}
for(int j = 0; j < 9; j++)
{
scanf("%d",&stEnd[j]);
}
int iRes = bfs();
if(iRes > 0)
{
printf("%d\n",iDist[iRes]);
}
else
{
printf("-1\n");
}
}
int main(int argc,char* argv[])
{
process();
system("pause");
return 0;
}
算法竞赛入门经典:第七章 暴力求解法 7.20八数码问题之stl
最新推荐文章于 2021-10-01 14:10:55 发布