双向广搜(DBFS)
双向广搜很早之前就像学习,但蒟蒻这道今天才会写(汗。。。)
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
八数码问题在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)相关推荐
- 双向广搜-HDU1401 Solitaire
文章目录 双向广搜 例题 题意 分析 代码 小结 双向广搜 什么是双向广搜? 如果把bfs想象成在平静的池塘丢一颗石头,激起的波浪一层层扩散到整个空间直到到达目标,就得到起点到终点的最优路径.那么双向 ...
- 【图论专题】BFS中的双向广搜 和 A-star
双向广搜 AcWing 190. 字串变换 #include <cstring> #include <iostream> #include <algorithm> ...
- 算法提高课-搜索-双向广搜 AcWing 190. 字串变换:bfs、双向bfs、queue和unordered_map
题目分析 来源:acwing 分析: 双向广搜主要用在最小步数模型(也称状态图模型)里面,这里整个状态空间一般是指数级别的,用双向广搜可以极大地提高运行效率. 双向广搜,顾名思义,就是从起点和终点都进 ...
- 双向广搜 8数码问题
转载自:http://blog.sina.com.cn/s/blog_8627bf080100ticx.html Eight 题目链接:http://acm.hdu.edu.cn/showprob ...
- poj 3131 Cubic Eight-Puzzle 双向广搜 Hash判重
挺不错的题目,很锻炼代码能力和调试能力~ 题意:初始格子状态固定,给你移动后格子的状态,问最少需要多少步能到达,如果步数大于30,输出-1. 由于单向搜索状态太多,搜到二十几就会爆了,所以应该想到双向 ...
- 万圣节后的早晨九数码游戏——双向广搜
https://www.luogu.org/problemnew/show/P1778 https://www.luogu.org/problemnew/show/P2578 双向广搜. 有固定起点终 ...
- POJ 1915(双向广搜)
应该是双向广搜的简单题,虽然写了很久.双向:简而言之就是从起点(正向搜索)和终点(逆向搜索)同时开始搜索,当两个搜索产生的一个子状态相同时就结束搜索. 通常有两种实现方法: 1.用一个队列来储存子状态 ...
- 小游戏系列算法之五广度优先搜索,双向广搜,八数码,华容道
前段时间在玩仙五前,遇上了蚩尤冢拼图这个小游戏. 其实就是八数码问题,一直想着如何才能用最少步数求解,于是就写了个程序. Q1:什么是八数码问题? A1:首先假定一个3*3的棋盘(如上图),分别有1, ...
- OpenJudge 6043 哆啦A梦的时光机——又短又快的双向广搜
题目链接 早上也写了一篇这道题关于双向广搜的题解,但那个写法有一个漏洞,而且很慢,在下面我将一一道来.我们知道,单向广搜时由起始点出发,引出4个分支,再由4个分支引出16个分支,可以看出这个增长速度是 ...
最新文章
- 用Python分析为什么在中国没学历的外教为啥能拿几万高薪?
- UWP 手绘视频创作工具技术分享系列 - 手绘视频导出
- mvc @html.checkbox,MVC - @Html.CheckBoxFor
- 《深入理解ES6》4.扩展的对象功能
- 结对开发2(求二维数组的最大子数组和)
- map 转 json格式string字符串
- sip协议详解 系列(一)
- 【Java实现PDF文件转换为图片】
- 微信小程序:使用普通链接二维码跳转到小程序,解析二维码携带参数(微信扫普通普通链接二维码和小程序里扫二维码解析参数方法)
- 移动硬盘内(或U盘)安装win10+kali(或其他linux)双系统,实现移动化办公
- 2022-爬虫-Selenium-百度安全验证
- 上网本丢失F盘怎么恢复
- TensorFlow在win10上安装--精简教程
- python——基础题
- SpringBoot + JWT + Redis 开源知识社区系统
- fpga nvme 寄存器
- 分享面经与面试资料-四面阿里终于如愿拿到P7级offer【Java岗】
- EBS WebADI:标准Web ADI模板@日记账导入
- Invalid bound statement (not found): com.web.sysmgr.mapper.UserMapper.login
- 我为什么放弃学术选择创业:这不仅仅关乎人工智能
热门文章
- 在物联网(IOT)的背景下是怎样定义物模型的
- 计算机二级c语言预测,计算机二级C语言考前预测上机试题及解析
- SAP MM物料主数据
- 【免费赠送源码】Springboot篮球网站19133计算机毕业设计-课程设计-期末作业-毕设程序代做
- java导出excel 方式_java导出Excel通用方法
- 超强整理:6大传感器原理
- isbn书号查询php代码,php根据isbn书号查询amazon网站上的图书信息的示例_PHP教程
- latex写中文毕业论文(北交大博士毕业论文模版)
- excel数字点一下才变为数值的批量快捷操作
- Prometheus源码学习(8) scrape总体流程