星星之火OIer:双向BFS(一)——八数码问题

双向BFS的前置知识请看这里辣

题目传送门

注意::LGOJ上的题和此处题目描述不太一样

每一行有9个数,空格间隔,组成3*3的矩形,两行数,求从第一个矩阵到第二个矩阵至少要移多少步,如果不能移动成目标样子,输出-1

基本思路

虽然仿佛可以用迭代加深做

但既然初始状态和目标状态都知道了

联系上一讲中的双向广搜

果断开始

但是要处理一下

让每一个状态都有唯一对应的hash

所以

补充知识

康拓展开&逆康拓展开

因为直接贴全排的话vis会开到vis[987654321]

肯定会爆

所以我们要用到康拓展开

康托&逆康拓展开

代码实现

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define it int
#define ll long long
#define il inline
#define bl bool
#define db double
#define rt return
#define vd void
#define ch char
#define wi while
#define br break
#define gc getchar
#define pc putchar
#define ct continue
il vd read(it &x) {
    x=0;
    it f=1;
    ch s=gc();
    wi(s<'0'||s>'9') {
        if(s=='-')
            f=-1;
        s=gc();
    }
    wi(s>='0'&&s<='9') {
        x=x*10+s-48;
        s=gc();
    }
    x*=f;
}
il vd pr(it x) {
    if(x<0) {
        pc('-');
        x=-x;
    }
    if(x>9)
        pr(x/10);
    pc(x%10+48);
}//快读快输不解释
ch a[10],mb[10];
it jc[]={1,1,2,6,24,120,720,5040,40320,362880}/*打个阶乘的表,方便康拓展开*/,step[2][362885]/*压缩之后只用开这么大*/,be,en,dir[4]={1,-1,3,-3},m;
bl vis[2][362885];
struct node {
	ch word[9];//当前状态
	it poss;
	bl flag;
	node(){}
	node(const ch a[],const it b,const bl c) {
		strcpy(word,a),poss=b,flag=c;
	}
}tmp;
queueq;
bl flag[10];
il it cantor(ch s[]) {//康拓展开
	memset(flag,1,sizeof(flag));
	it ans=0,temp;
	for(it i=0;i<9;i++) {
		flag[s[i]-'0']=0;
		temp=0;
		for(it j=0;j=0&&wz<9&&(wz/3==pos/3||wz%3==pos%3)) {//是否在界内&&是否走得到
				swap(tmp.word[wz],tmp.word[pos]);//交换
				temp2=cantor(tmp.word);//标记已走过
				if(!vis[tmp.flag][temp2]) {
					vis[tmp.flag][temp2]=1;
					step[tmp.flag][temp2]=step[tmp.flag][temp]+1;//步数++
					q.push(node(tmp.word,wz,tmp.flag));//入队
				}
				swap(tmp.word[wz],tmp.word[pos]);//回溯
			}
		}
	}
	rt -1;
}
it main() {
	for(it i=0;i<9;i++) {//读入初始状态数组
		read(m);
		a[i]=m+48;
		if(m==0)
			be=i;//起点空位
	}
	for(it i=0;i<9;i++) {//读入目标状态数组
		read(m);
		mb[i]=m+48;
		if(m==0)
			en=i;//终点空位
	}
	pr(dbbfs());
}

大概就是这样了,不同的一起讨论讨论,一起学习

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