题目链接
早上也写了一篇这道题关于双向广搜的题解,但那个写法有一个漏洞,而且很慢,在下面我将一一道来。我们知道,单向广搜时由起始点出发,引出4个分支,再由4个分支引出16个分支,可以看出这个增长速度是非常快的,而且随着搜索层数递增。于是加入双向广搜进行时间优化,双向广搜是由起点和终点两个点出发不断交替引出分支,当两者的分支发生碰撞时就可以得出答案了。重要的是”交替”两个字,不是指两边交替着一个一个引出分支,而是一层一层地引出分支(这里指一个步数一个步数地引出),原因很简单,一个一个引出分支可能会导致答案更大,也就是原先可以以x+1步引出的数,现在要以x+2步引出,显然错误。
另外还有三个优化的方法:1.每次BFS前不需要将step初始化,因为一个数的visit如果更新了,那么它的step也会更新;2.其实visit也不需要初始化,只要每次记下这是第几组数据,然后给对应的正向搜索和反向搜索编上号就行了;3.可以将系统队列转化为自定义的数组,这显然可以加快时间,而且可以只开在一个数组里,只要一个由左往右,一个由右往左就行了。
下面给出代码。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define M 2000005
using namespace std;
template <class T>
inline void Rd(T &res){char c;res=0;int k=1;while(c=getchar(),c<48&&c!='-');if(c=='-'){k=-1;c='0';}do{res=(res<<3)+(res<<1)+(c^48);}while(c=getchar(),c>=48);res*=k;
}
bool found;
int Q[M];
int visit[M];//存节点是否被遍历过,0为正向遍历过,1为反向遍历过,-1为未遍历
int step0[M];//正向搜索的步数保存
int step1[M];//反向搜索的步数保存
int res;//搜索到的共同节点
bool check(int k,int x){if(k==0)return x+1<M;if(k==1)return x-1>0;if(k==2)return 2*x<M;return !(x&1);
}
int f(int k,int x){if(k==0)return x+1;if(k==1)return x-1;if(k==2)return 2*x;return x/2;
}
void bfs(int &L,int &R,bool flag,int time){int x;if(!flag)x=Q[L++];else x=Q[R--];int step;if(!flag)step=step0[x];else step=step1[x];for(int i=0;i<4;i++)if(check(i,x)){int nx=f(i,x);if(!flag){//在正向队列中判断 if(visit[nx]!=time){//未在正向队列中出现step0[nx]=step+1;if(visit[nx]==time+1){found=true;res=nx;return;     }visit[nx]=time;Q[R++]=nx;}}else{//在反向队列中判断 if(visit[nx]!=time+1){//未在反向队列中出现 step1[nx]=step+1;if(visit[nx]==time){found=true;res=nx;return;}visit[nx]=time+1;Q[L--]=nx;}}}
}
void BFS(int s,int t,int time){found=false;visit[s]=time,visit[t]=time+1,step0[s]=0,step1[t]=0;int L0=0,R0=0,L1=1999999,R1=1999999;Q[R0++]=s;Q[L1--]=t;while(L0<R0||L1<R1){int R=R0;while(L0<R)bfs(L0,R0,0,time);if(found)return;int L=L1;while(L<R1)bfs(L1,R1,1,time);if(found)return;}
}
int T,s,t;
int main(){memset(visit,-1,sizeof(visit));Rd(T);while(T--){Rd(s);Rd(t);BFS(s,t,T<<1);printf("%d\n",2*(step0[res]+step1[res]));}return 0;
}

另外,这里有一个提醒:慎用位运算,因为位运算的优先级有一些古怪,容易造成一些错误,博主就因为这个问题WA了好多次。

此题虐我千百遍,誓待此题如初恋/(ㄒoㄒ)/~~

OpenJudge 6043 哆啦A梦的时光机——又短又快的双向广搜相关推荐

  1. NOI openjudge 6043:哆啦A梦的时光机(双向宽搜)

    在线评测: http://noi.openjudge.cn/ch0407/6043/ 整体思路: 这种题随便宽搜一下就好了,没啥思路可讲,,,, 失误之处: 1.开始脑子里想的是一面扩展一层,这样子可 ...

  2. [openjudge6043]哆啦A梦的时光机

    [openjudge6043]哆啦A梦的时光机 试题描述 哆啦A梦有一个神奇的道具:时光机.坐着它,大雄和他的伙伴们能穿越时空,回到过去或者去到未来. 有一天,大雄和他的伙伴们想穿越时空进行探险,可是 ...

  3. 【搜索】C042_openj_哆啦A梦的时光机(暴力 / 记忆化)

    一.Problem 哆啦A梦有一个神奇的道具:时光机.坐着它,大雄和他的伙伴们能穿越时空,回到过去或者去到未来. 有一天,大雄和他的伙伴们想穿越时空进行探险,可是时光机却出了一点故障,只能进行有限的时 ...

  4. #I. 哆啦A梦的时光机(bfs经典习题)

    题目 说明 有一天,大雄和他的伙伴们想穿越时空进行探险,可是时光机却出了一点故障,只能进行有限的时空穿越操作.大雄他们需要从现在出发,到达一个目标时间点进行探险,结束后再返回到现在,他们希望尽可能减少 ...

  5. 8.20 最小新整数 哆啦A梦的时光机(bfs)

    给定一个十进制正整数 n(0 < n < 1000000000),每个数位上数字均不为 0.n 的位数为 m. 现在从 m 位中删除 k 位 (0<k < m),求生成的新整数 ...

  6. Git,哆啦A梦的时光机(二)

    上一篇介绍了Git的作用和优势,本篇就仔细说一说Git到底是什么. 1.到底什么是Git? 组成部分 进入Git官网直接下载安装,https://git-scm.com/downloads 如图所示为 ...

  7. HTML5期末大作业:动漫人物介绍网站设计——哆啦A梦(5页) HTML+CSS+JavaScript 学生动漫网页设计模板下载 哆啦A大学生HTML网页制作作品 简单漫画网页设计成品...

    常见网页设计作业题材有 ​​个人. 美食. 公司. 学校. 旅游. 电商. 宠物. 电器. 茶叶. 家居. 酒店. 舞蹈. 动漫. 明星. 服装. 体育. 化妆品. 物流. 环保. 书籍. 婚纱. 游 ...

  8. 再过92年,哆啦A梦就要诞生了!

    还记得哆啦A梦是从哪一年出生的吗? 2112年9月3日. 也就是说,再过92年,哆啦A梦,也许就能诞生了. 很多人的童年,或许都有这么一只哆啦,可以成为我们的伙伴. 虽然这些幻想存在于童年,但它的出现 ...

  9. python哆啦a梦的百宝箱_你最想要哆啦A梦百宝箱里的什么东西

    五月天有一句关于哆啦A梦的歌词:  "如果说最后宜静不是嫁给了大雄,一生相信的执着一秒就崩落"或许每个在哆啦A梦的故事中成长起来的孩子都期待着自己也能有一个属于自己的机器猫那只没有 ...

最新文章

  1. 用word2007发布blog
  2. 【数据挖掘】数据挖掘总结 ( K-Means 聚类算法 | 二维数据的 K-Means 聚类 ) ★
  3. 从Wasserstein距离、对偶理论到WGAN
  4. Linux命令终端如何查询本机的内外网IP地址
  5. Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean 解决方案
  6. VUE3@/cli数据交互(axios)
  7. 养老金总额和个人账户本息总额啥区别,退休后按照哪个账户计算养老金呢?
  8. 食物链(扩展域并查集)
  9. UVA11752 The Super Powers【超级幂+暴力+数论】
  10. matlab求方程实根,简单迭代法求方程根的MATLAB程序
  11. DSOframer 的简单介绍和资源整理(2015-09-02重新整理)
  12. 月薪30K+的电子工程师应具备什么?
  13. 基于89C51单片机的智能语音拨号电话
  14. 招投标信息爬虫 (只上最简单的版本,仅用于技术交流)
  15. vue的事件修饰符之.prevent
  16. MT【99】2005联赛二试题我的一行解法
  17. 电脑误删wps文件怎么恢复?介绍4个解决方法
  18. python输出两个元素空格隔开_python实现将一串字符每两个一组,中间用空格隔开...
  19. Thinkadmin v6爆高危漏洞!
  20. Linux安全防护【云锁】

热门文章

  1. 互联网早报:华为高精度地图拟年内商用,正在一线城市采集数据
  2. 新颖且有价值的想法在哪里以及如何产生的?与产生相关的后颞叶和与执行控制相关的前额叶皮层的tDCS
  3. BIM模型HLoD设计文档
  4. Linux内核中断号映射过程分析(三)
  5. yaf mysql_yaf集成medoo数据库操作
  6. [文献阅读]——ERNIE-Gram: Pre-Training with Explicitly N-Gram Masked Language Modeling for NLU(TBC)
  7. 音视频最新技术有哪些
  8. 司马相如 和 卓文君
  9. 鲜为人知的mysql导入数据
  10. 软件开发相关的读书笔记 问题与方法