else {
扩展q2;(包括判断,入队,更新)if(扩展出在q1 扩展过的节点)得解+return 1;}
}
while(q1不为空)
{扩展q1;(包括判断,入队,更新);if(扩展出在q2 扩展过的节点)得解+return 1;
while(q2不为空)
{扩展q2;(包括判断,入队,更新);if(扩展出在q1 扩展过的节点)得解+return 1;
return 1;
}
本题注意事项:如果要压数字的话,记得处理 0 在,末尾或 开头(尤其是0在头部(我懒,就把 123456780 -> 234567891)
swap更新的时候,下标要和自己的数组对上,,,(我傻,,,正好错开一位,,竟然过样例了XD)
dis更新的时候,下标可以和hash的下标对应,hash的时候,取余的质数要> 9 ! (<-这是阶乘
如果你们哪个大神会康拓展开,可以做到hash不挂表;
emm文末贴acer友链(我知道你们都是去看他的IDA的 ((¬︿̫̿¬☆))山 )(我的比他的快(傲娇脸))
贴代码(一点点注释)
#include
#include
#include
#include
#include
#include
using namespace std;
#define M 883783//比P大
#define P 383783//P 要大于 9得阶乘 ,因为。。数学
int hash[M][3],a[10],nxt[M][3],xx;
int dis[M][3];
int dir[9][5]={
{-1,-1,3,1},{-1,0,4,2},{-1,1,5,-1},
{0,-1,6,4},{1,3,7,5},{2,4,8,-1},
{3,-1,-1,7},{4,6,-1,8},{5,7,-1,-1}
}; //dir[当前0的位置][可以swap到哪里去]//-1为不能动,记得判
int insert(int x,int num){ //自己YY 的hash简陋的不行不行的 //记得分开插入
int flag=0;int cnt=x%P+1;
while(hash[cnt][num]!=-1){
flag=1;cnt++;if(cnt>=M)return 0;
}
if(flag)nxt[x%P][num]=cnt;
hash[cnt][num]=x;
return 1;
}
int get(int x,int num){ //查询是否存在,以及若存在,其下标为何 //分开查找
int sub=x%P+1;
if(hash[sub][num]==x)return sub;
while(hash[nxt[sub][num]][num]!=x){
if((nxt[sub][num]==-1)||(hash[nxt[sub][num]][num]==-1))return 0;
sub=nxt[sub][num];
}return sub;
}
int pullout(int x[10]){int num=x[0];for(int i=1;i<9;i++){num=num*10;num+=x[i];}return num;}//自己YY的从数组压成数
int pullin(int num){for(int i=8;i>=0;i--){a[i]=num%10;num/=10;}return 0;}//YY的数组搞回数
queueq;queueq2;// <-队列在这
int expand(int num){//扩展函数,兼带判重 入队 得解,
int c[10],sub,now;
if(num==1){
now=q.front();q.pop();
}else {
now=q2.front();q2.pop();
}
pullin(now);
for(int i=0;i<9;i++){if(a[i]==1){sub=i;break;}}
for(int i=0;i<4;i++){
if(dir[sub][i]==-1)continue;
memcpy(c,a,sizeof(c));//一个扩展成四个(二个)
swap(c[sub],c[dir[sub][i]]);
int xx=pullout(c);//printf("xx=%d\n",xx);
if(!get(xx,num)){
insert(xx,num);dis[get(xx,num)][num]=dis[get(now,num)][num]+1;
if(get(xx,3-num)){//查另一个队列是否有值
printf("%d\n",dis[get(xx,num)][num]+dis[get(xx,3-num)][3-num]);
return 1;
}
if(num==1){q.push(xx);}else {q2.push(xx);}
}
}return 0;
}
int BFSdouble(int s,int end){//DBFS框架
q.push(s);q2.push(end);
insert(s,1);insert(end,2);
dis[get(s,1)][1]=0;dis[get(end,2)][2]=0;
while(q.size()&&q2.size()){
if(q.size()
顺带发一下我的hash(主要在思想),网上的很麻烦的样子,,(一堆指针写的)
#include
#include
#include
#include
#include
#include
using namespace std;
#define M 683783
#define P 20
int hash[M],nxt[M],xx;
int insert(int x){
int flag=0;int cnt=x%P+1;
while(hash[cnt]!=-1){
flag=1;cnt++;
}
if(flag)nxt[x%P]=cnt;
hash[cnt]=x;printf("numbernow's cnt=%d\n",cnt);
return 1;
}
int get(int x){
int sub=x%P+1;
if(hash[sub]==x){return sub;}
while(hash[sub]!=x){
if((nxt[sub]==-1)||(hash[nxt[sub]]==-1))return 0;
sub=nxt[sub];
}return sub;
}
int main(){
memset(hash,-1,sizeof(hash));
memset(nxt,-1,sizeof(nxt));
scanf("%d",&xx);insert(xx);//输入一个数
while(1){//查询某个数
scanf("%d",&xx);
int ans=get(xx);
if(ans)printf("sub for number=%d\n",ans);
else puts("Nope!");
}
}
友链: go