ACM-BFS之Open the Lock——hdu1195(双向BFS)
这道题的0基础版本号,暴力BFS及题目详情请戳:http://blog.csdn.net/lttree/article/details/24658031
上回书说道,要用双向BFS来尝试一下。
最终AC了,
双向BFS,就是从两个点寻找一个共同的中间点。
然后把各自到这个中间点的步数加起来,及为最短步数。
肯定有人问了。双向BFS有啥优点捏?
鄙人,有图有真相!
单BFS:
双向BFS:
发现了不?
尤其是随着搜索广度的增大。那个范围是相当di啊!
双向BFS做法事实上不难,两个队列。
一个从头開始搜。一个从尾開始搜。
可是要注意一点,要逐层搜索。不要逐点搜索呀~
要在 正向的同一层搜索完后,再去搜索反向的对应层!
什么叫逐层搜索呢?
对于这道题而言,VIS数组须要记录到达该点的步数,
对于每层搜索要把,同一步数的点全出队列遍历一遍,再进行反向搜索。
OK。这是对于这道题的双向广搜代码(感觉就是把两个广搜叠起来就OK了)
/**************************************
***************************************
* Author:Tree *
*From :http://blog.csdn.net/lttree *
* Title : Scrambled Polygon *
*Source: hdu 1195 *
* Hint : 双向BFS *
***************************************
**************************************/ #include <iostream>
#include <string.h>
#include <queue>
using namespace std;
struct VIS
{
int flag,step;
}vis[10001];
struct Key
{
int k[4],step;
friend bool operator <(Key a,Key b)
{
return a.step<b.step;
}
};
int ini[4],ans[4],dis[2]={-1,1};
int solu[9]={9,1,2,3,4,5,6,7,8};
bool judge(Key a)
{
for(int i=0;i<4;++i)
if( a.k[i]!=ans[i] )
return false;
return true;
}
// 用来做VIS数组
int total(Key a)
{
int i,sum;
sum=0;
for(i=0;i<4;++i)
sum=sum*10+a.k[i];
return sum;
}
int bfs(void)
{
memset(vis,0,sizeof(vis));
queue <Key> q;
queue <Key> p;
Key pre,lst;
int i,t,sum,sp=0; // 初始化。。。 for(i=0;i<4;++i)
pre.k[i]=ini[i];
sum=total(pre);
vis[sum].flag=1;
vis[sum].step=0;
pre.step=0;
q.push(pre); for(i=0;i<4;++i)
lst.k[i]=ans[i];
sum=total(lst);
vis[sum].flag=2;
vis[sum].step=0;
lst.step=0;
p.push(lst); while( !q.empty() && !p.empty() )
{
// 为了遍历每一层的情况,所以用sp来控制层数
// 正向搜索
while( q.front().step==sp )
{
pre=q.front();
q.pop();
for(i=0; i<4; ++i)
{
if( pre.k[i]!=ans[i] )
{
for(t=0; t<2; ++t)
{
lst=pre;
lst.k[i]=solu[(pre.k[i]+dis[t])%9];
sum=total(lst);
lst.step=pre.step+1;
if( vis[sum].flag==1 ) continue;
if( vis[sum].flag==2 ) return lst.step+vis[sum].step;
vis[sum].flag=1;
vis[sum].step=lst.step;
q.push(lst);
}
}
}
for(i=0; i<3; ++i)
{
lst=pre;
lst.k[i]=pre.k[i+1];
lst.k[i+1]=pre.k[i];
sum=total(lst);
lst.step=pre.step+1;
if( vis[sum].flag==1 ) continue;
if( vis[sum].flag==2 ) return lst.step+vis[sum].step;
vis[sum].flag=1;
vis[sum].step=lst.step;
q.push(lst);
}
}
// 反向搜索
while( p.front().step==sp )
{
pre=p.front();
p.pop(); for(i=0; i<4; ++i)
{
if( pre.k[i]!=ini[i] )
{
for(t=0; t<2; ++t)
{
lst=pre;
lst.k[i]=solu[(pre.k[i]+dis[t])%9];
sum=total(lst);
lst.step=pre.step+1;
if( vis[sum].flag==2 ) continue;
if( vis[sum].flag==1 ) return lst.step+vis[sum].step;
vis[sum].flag=2;
vis[sum].step=lst.step;
p.push(lst);
}
}
} for(i=0; i<3; ++i)
{
lst=pre;
lst.k[i]=pre.k[i+1];
lst.k[i+1]=pre.k[i];
sum=total(lst);
lst.step=pre.step+1;
if( vis[sum].flag==2 ) continue;
if( vis[sum].flag==1 ) return lst.step+vis[sum].step; vis[sum].flag=2;
vis[sum].step=lst.step;
p.push(lst);
}
}
++sp;
}
}
int main()
{
int i,s,test;
char c;
cin>>test;
while( test-- )
{
// 输入数据
for(i=0;i<4;++i)
{
cin>>c;
ini[i]=c-'0';
}
for(i=0;i<4;++i)
{
cin>>c;
ans[i]=c-'0';
} s=bfs();
cout<<s<<endl;
}
return 0;
}
ACM-BFS之Open the Lock——hdu1195(双向BFS)的更多相关文章
- HDU1195 双向BFS(或BFS)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1195 , 双向BFS或者直接BFS也可以过. 其实这道题只是单向BFS就可以过的,但是为了练算法,所以 ...
- HDU——1195Open the Lock(双向BFS)
Open the Lock Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
- HDU 3085 Nightmare II 双向bfs 难度:2
http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...
- 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...
- HDU 1043 Eight(双向BFS+康托展开)
http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...
- HDU 3085 Nightmare Ⅱ(双向BFS)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 题目大意:给你一张n*m地图上,上面有有 ‘. ’:路 ‘X':墙 ’Z':鬼,每秒移动2步,可 ...
- HDU3085 Nightmare Ⅱ —— 双向BFS + 曼哈顿距离
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 Nightmare Ⅱ Time Limit: 2000/1000 MS (Java/Other ...
- HDU1401(双向BFS)
题意:http://acm.hdu.edu.cn/showproblem.php?pid=1401 给你8*8的棋盘和4个棋子初始位置.最终位置,问你能否在8次操作后达到该状态. 思路: 双向BFS, ...
- HDU3085NightmareII题解--双向BFS
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=3085 分析 大意就是一个男孩和一个女孩在网格里,同时还有两个鬼,男孩每轮走三步,女孩每轮走一步,与鬼曼 ...
随机推荐
- 如何应对pm2.5
细颗粒物又称细粒.细颗粒.PM2.5:指环境空气中空气动力学当量直径小于等于 2.5 微米的颗粒物,也称细颗粒物.能较长时间悬浮于空气中,其在空气中含量(浓度)越高,就代表空气污染越严重.可吸入颗粒物 ...
- 开始学习es6(二) let 与 const 及 块级作用域
1.var JavaScript中,我们通常说的作用域是函数作用域,使用var声明的变量,无论是在代码的哪个地方声明的,都会提升到当前作用域的最顶部,这种行为叫做变量提升(Hoisting) cons ...
- Linux 虚拟地址与物理地址的映射关系分析【转】
转自:http://blog.csdn.net/ordeder/article/details/41630945 版权声明:本文为博主(http://blog.csdn.net/ordeder)原创文 ...
- Linux之进程的等待与其内核实现解析
进程通过fork产生子进程,进程也会死亡,进程退出的时候将会进行内核清理,释放所有进程的资源,资源包括:内存资源,文件资源,信号量资源,共享内存资源,或者引用计数减一,或者彻底释放. 不过进程 ...
- 用python生成二维码
Python生成二维码,可以使用qrcode模块, github地址 我是搬运工 首先安装, 因为打算生成好再展示出来,所以用到Pillow模块 pip install qrcode pip inst ...
- Yii关联查询(转载)
原文链接:http://keshion.iteye.com/blog/1607994 一.多表关联的配置 在我们使用 AR 执行关联查询之前,我们需要让 AR 知道一个 AR 类是怎样关联到另一个的. ...
- 这是一份很有诚意的2017 Google I/O大会的汇总 & 解析
前言 在刚过去的凌晨(北京时间 5月18日 1.00-3.00),一年一度的2017年Google I/O大会在美国谷歌山景城海岸线圆形剧场如期举行 Google I/O 大会:Innovation ...
- 专访Nick McKeown:网络领域的游戏颠覆者
如果要找到一个过去10年在网络领域最热的词汇,那么非SDN(软件定义网络)莫属.在过去的十年间无论是学术机构还是标准组织,无论是电信巨擘还是互联网大厂都成其拥趸. 然而几乎每一件SDN的重大事件都离不 ...
- Codeforces Round #321 (Div. 2) Kefa and Park 深搜
原题链接: 题意: 给你一棵有根树,某些节点的权值是1,其他的是0,问你从根到叶子节点的权值和不超过m的路径有多少条. 题解: 直接dfs一下就好了. 代码: #include<iostream ...
- 使用一个数组存储一个英文句子"java is an object oriented programing language"
class fun { public static void main(String[] args) { String str="java is an object oriented pro ...