双向广搜很早之前就像学习,但蒟蒻这道今天才会写(汗。。。)

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

八数码问题在oi界也算是妇孺皆知,有启发式搜索和DBFS两种解法,题目不在详细介绍,在这里给出我的解法

codevs 1225 八数码难题

比较原始的八数码,目标状态为123804765(即蛇形排列),双向广搜顾名思义,就是两头同时进行广搜,我们有了起点状态和目标状态,可以同时扩展,这道扩展出同一个叶子节点,注意hash判重,queue中的st为步数,col表示是从正序扩展而来还是从逆序扩展而来,exist存放编号,一旦出现hash值相同但col不同,就查询出来节点编号,把st相加即为结果。 code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
int en[4][4]={0,0,0,0,0,1,2,3,0,8,0,4,0,7,6,5},st[4][4],head,tail;
int dx[5]={0,1,0,-1,0},dy[5]={0,0,1,0,-1};
int exist[500001][2];
struct hp{int map[4][4],bx,by,col,st;
}queue[500001];
int hash(int i)
{int j,k,m,p,sum=0,x;for (j=1;j<=3;++j)for (k=1;k<=3;++k){x=0;for (p=k+1;p<=3;++p)x+=queue[i].map[j][k]>queue[i].map[j][p];for (p=j+1;p<=3;++p)for (m=1;m<=3;++m)x+=queue[i].map[j][k]>queue[i].map[p][m];sum+=x*fac[9-(j-1)*3-k];   }return sum;
}
void init()
{int i,j;char c;for (i=1;i<=3;++i)for (j=1;j<=3;++j){scanf("%c",&c);st[i][j]=int(c)-48;}
}
int bfs()
{int bx1,by1,i,j,k,m,e,step,temp,std;head=0; tail=2;for (i=1;i<=3;++i)for (j=1;j<=3;++j){queue[2].map[i][j]=en[i][j];queue[1].map[i][j]=st[i][j];if (st[i][j]==0){queue[1].bx=i;queue[1].by=j;}if (en[i][j]==0){queue[2].bx=i;queue[2].by=j;}}queue[1].col=0; queue[2].col=1;queue[1].st=queue[2].st=0;memset(exist,0,sizeof(exist));exist[hash(1)][0]=1; exist[hash(2)][1]=2; step=0;while (head<tail){e=tail; head++; step++;for (i=head;i<=e;++i){bx1=queue[i].bx;by1=queue[i].by;for (j=1;j<=4;++j)if (bx1+dx[j]>=1&&bx1+dx[j]<=3&&by1+dy[j]>=1&&by1+dy[j]<=3){tail++;for (k=1;k<=3;++k)for (m=1;m<=3;++m)queue[tail].map[k][m]=queue[i].map[k][m];queue[tail].bx=bx1+dx[j];queue[tail].by=by1+dy[j];queue[tail].map[bx1+dx[j]][by1+dy[j]]=0;queue[tail].map[bx1][by1]=queue[i].map[bx1+dx[j]][by1+dy[j]];queue[tail].col=queue[i].col;queue[tail].st=step;temp=hash(tail);if (exist[temp][queue[tail].col]) tail--;else{exist[temp][queue[tail].col]=tail;if (exist[temp][1-queue[tail].col])return step+queue[exist[temp][1-queue[tail].col]].st;}  }  }head=e;}return -1;
}
int main()
{int num;init();num=bfs();if (num!=-1)printf("%d\n",num);elseprintf("unsolvable\n");
}

poj 1077 Eight 输出路径的八数码,稍麻烦 code:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int fac[10]={1,1,2,6,24,120,720,5040,40320,362880};
int en[4][4]={0,0,0,0,0,1,2,3,0,4,5,6,0,7,8,0},st[4][4],head,tail;
int dx[5]={0,1,0,-1,0},dy[5]={0,0,1,0,-1};
int exist[500001][2];
struct hp{int map[4][4],bx,by,col,st,last;char mov;
}queue[500001];
int hash(int i)
{int j,k,m,p,sum=0,x;for (j=1;j<=3;++j)for (k=1;k<=3;++k){x=0;for (p=k+1;p<=3;++p)x+=queue[i].map[j][k]>queue[i].map[j][p];for (p=j+1;p<=3;++p)for (m=1;m<=3;++m)x+=queue[i].map[j][k]>queue[i].map[p][m];sum+=x*fac[9-(j-1)*3-k];   }return sum;
}
void init()
{int i,j;char c;for (i=1;i<=3;++i)for (j=1;j<=3;++j){scanf("%c",&c);if (c==' ')scanf("%c",&c);if (c!='x')st[i][j]=int(c)-48;elsest[i][j]=0;}
}
void print1(int mid)
{if (queue[mid].last!=1)print1(queue[mid].last);printf("%c",queue[mid].mov);
}
void print2(int mid)
{printf("%c",queue[mid].mov);if (queue[mid].last!=2)print2(queue[mid].last);
}
int bfs()
{int bx1,by1,i,j,k,m,e,step,temp,std;head=0; tail=2;for (i=1;i<=3;++i)for (j=1;j<=3;++j){queue[2].map[i][j]=en[i][j];queue[1].map[i][j]=st[i][j];if (st[i][j]==0){queue[1].bx=i;queue[1].by=j;}if (en[i][j]==0){queue[2].bx=i;queue[2].by=j;}}queue[1].col=0; queue[2].col=1;queue[1].st=queue[2].st=0;memset(exist,0,sizeof(exist));exist[hash(1)][0]=1; exist[hash(2)][1]=2; step=0;while (head<tail){e=tail; head++; step++;for (i=head;i<=e;++i){bx1=queue[i].bx;by1=queue[i].by;for (j=1;j<=4;++j)if (bx1+dx[j]>=1&&bx1+dx[j]<=3&&by1+dy[j]>=1&&by1+dy[j]<=3){tail++;for (k=1;k<=3;++k)for (m=1;m<=3;++m)queue[tail].map[k][m]=queue[i].map[k][m];queue[tail].bx=bx1+dx[j];queue[tail].by=by1+dy[j];queue[tail].map[bx1+dx[j]][by1+dy[j]]=0;queue[tail].map[bx1][by1]=queue[i].map[bx1+dx[j]][by1+dy[j]];queue[tail].col=queue[i].col;queue[tail].st=step;queue[tail].last=i;if (queue[tail].col==0){if (j==1) queue[tail].mov='d';if (j==2) queue[tail].mov='r';if (j==3) queue[tail].mov='u';if (j==4) queue[tail].mov='l';}if (queue[tail].col==1){if (j==1) queue[tail].mov='u';if (j==2) queue[tail].mov='l';if (j==3) queue[tail].mov='d';if (j==4) queue[tail].mov='r';}temp=hash(tail);if (exist[temp][queue[tail].col]) tail--;else{exist[temp][queue[tail].col]=tail;if (exist[temp][1-queue[tail].col]){if (queue[tail].col==0){print1(tail);print2(exist[temp][1-queue[tail].col]);}else{print1(exist[temp][1-queue[tail].col]);print2(tail);}return step+queue[exist[temp][1-queue[tail].col]].st;}}  }  }head=e;}return -1;
}
int main()
{int num;init();num=bfs();if (num==-1)printf("unsolvable\n");
}

双向广搜(DBFS)相关推荐

  1. 双向广搜-HDU1401 Solitaire

    文章目录 双向广搜 例题 题意 分析 代码 小结 双向广搜 什么是双向广搜? 如果把bfs想象成在平静的池塘丢一颗石头,激起的波浪一层层扩散到整个空间直到到达目标,就得到起点到终点的最优路径.那么双向 ...

  2. 【图论专题】BFS中的双向广搜 和 A-star

    双向广搜 AcWing 190. 字串变换 #include <cstring> #include <iostream> #include <algorithm> ...

  3. 算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map

    题目分析 来源:acwing 分析: 双向广搜主要用在最小步数模型(也称状态图模型)里面,这里整个状态空间一般是指数级别的,用双向广搜可以极大地提高运行效率. 双向广搜,顾名思义,就是从起点和终点都进 ...

  4. 双向广搜 8数码问题

     转载自:http://blog.sina.com.cn/s/blog_8627bf080100ticx.html  Eight 题目链接:http://acm.hdu.edu.cn/showprob ...

  5. poj 3131 Cubic Eight-Puzzle 双向广搜 Hash判重

    挺不错的题目,很锻炼代码能力和调试能力~ 题意:初始格子状态固定,给你移动后格子的状态,问最少需要多少步能到达,如果步数大于30,输出-1. 由于单向搜索状态太多,搜到二十几就会爆了,所以应该想到双向 ...

  6. 万圣节后的早晨九数码游戏——双向广搜

    https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...

  7. POJ 1915(双向广搜)

    应该是双向广搜的简单题,虽然写了很久.双向:简而言之就是从起点(正向搜索)和终点(逆向搜索)同时开始搜索,当两个搜索产生的一个子状态相同时就结束搜索. 通常有两种实现方法: 1.用一个队列来储存子状态 ...

  8. 小游戏系列算法之五广度优先搜索,双向广搜,八数码,华容道

    前段时间在玩仙五前,遇上了蚩尤冢拼图这个小游戏. 其实就是八数码问题,一直想着如何才能用最少步数求解,于是就写了个程序. Q1:什么是八数码问题? A1:首先假定一个3*3的棋盘(如上图),分别有1, ...

  9. OpenJudge 6043 哆啦A梦的时光机——又短又快的双向广搜

    题目链接 早上也写了一篇这道题关于双向广搜的题解,但那个写法有一个漏洞,而且很慢,在下面我将一一道来.我们知道,单向广搜时由起始点出发,引出4个分支,再由4个分支引出16个分支,可以看出这个增长速度是 ...

最新文章

  1. 用Python分析为什么在中国没学历的外教为啥能拿几万高薪?
  2. UWP 手绘视频创作工具技术分享系列 - 手绘视频导出
  3. mvc @html.checkbox,MVC - @Html.CheckBoxFor
  4. 《深入理解ES6》4.扩展的对象功能
  5. 结对开发2(求二维数组的最大子数组和)
  6. map 转 json格式string字符串
  7. sip协议详解 系列(一)
  8. 【Java实现PDF文件转换为图片】
  9. 微信小程序:使用普通链接二维码跳转到小程序,解析二维码携带参数(微信扫普通普通链接二维码和小程序里扫二维码解析参数方法)
  10. 移动硬盘内(或U盘)安装win10+kali(或其他linux)双系统,实现移动化办公
  11. 2022-爬虫-Selenium-百度安全验证
  12. 上网本丢失F盘怎么恢复
  13. TensorFlow在win10上安装--精简教程
  14. python——基础题
  15. SpringBoot + JWT + Redis 开源知识社区系统
  16. fpga nvme 寄存器
  17. 分享面经与面试资料-四面阿里终于如愿拿到P7级offer【Java岗】
  18. EBS WebADI:标准Web ADI模板@日记账导入
  19. Invalid bound statement (not found): com.web.sysmgr.mapper.UserMapper.login
  20. 我为什么放弃学术选择创业:这不仅仅关乎人工智能

热门文章

  1. 在物联网(IOT)的背景下是怎样定义物模型的
  2. 计算机二级c语言预测,计算机二级C语言考前预测上机试题及解析
  3. SAP MM物料主数据
  4. 【免费赠送源码】Springboot篮球网站19133计算机毕业设计-课程设计-期末作业-毕设程序代做
  5. java导出excel 方式_java导出Excel通用方法
  6. 超强整理:6大传感器原理
  7. isbn书号查询php代码,php根据isbn书号查询amazon网站上的图书信息的示例_PHP教程
  8. latex写中文毕业论文(北交大博士毕业论文模版)
  9. excel数字点一下才变为数值的批量快捷操作
  10. Prometheus源码学习(8) scrape总体流程