Open the Lock

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 6016    Accepted Submission(s): 2680

Problem Description
Now an emergent task for you is to open a password lock. The password is consisted of four digits. Each digit is numbered from 1 to 9. 
Each time, you can add or minus 1 to any digit. When add 1 to '9', the digit will change to be '1' and when minus 1 to '1', the digit will change to be '9'. You can also exchange the digit with its neighbor. Each action will take one step.

Now your task is to use minimal steps to open the lock.

Note: The leftmost digit is not the neighbor of the rightmost digit.

 
Input
The input file begins with an integer T, indicating the number of test cases.

Each test case begins with a four digit N, indicating the initial state of the password lock. Then followed a line with anotther four dight M, indicating the password which can open the lock. There is one blank line after each test case.

 
Output
For each test case, print the minimal steps in one line.
 
Sample Input
2
1234
2144

1111
9999

 
Sample Output
2
4
 
Author
YE, Kai

最近懂了点BFS套路,这题用普通BFS本来就是大水题一道,但是可以用双向BFS写,据说若干若原来复杂度为K^n,则双向会大约是2*K^(n/2)。在POJ上的题目比较明显,从400+MS降到16MS。但是这题两者都是62MS(我搞了半天这结果一样……)代码WA很久,不解一个下午,也改了很久,看了很多其他人写的这题的题解,代码量比较大而且我使用字符数组他们是转换为int。方式不同也看起来比较复杂不太能懂。但是想起来中途看到一篇讲双向BFS的文章双向BFS,然后发现自己跟作者讲的情况很符合,似乎是搜索的时候跳出太快了,没有搜完就结束了。也就是所谓的每一层都要搜遍。然后按照作者所说加了个队列数量判断来保持两个搜索队列大小相对平衡,然后就开心地过了。

双搜WA的可以看下这组数据(类似于答案应该是前两位交换,后两位加减):

5
1919
9128

原来代码答案是4,但其实是3(1、9交换,后面加减)。

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define MM(x) memset(x,0,sizeof(x))
#define MMINF(x) memset(x,INF,sizeof(x))
typedef long long LL;
const double PI=acos(-1.0);
const int N=100010;
struct info
{
char s[5];
int step;
};
info goal,ori;
int pos[N];
int vis[N];
inline int change(char s[])
{
int r=0;
for (int i=0; i<4; ++i)
r=r*10+s[i]-'0';
return r;
}
int T_bfs()
{
queue<info>Qf;
queue<info>Qb;
Qf.push(ori);
Qb.push(goal);
while ((!Qf.empty())||(!Qb.empty()))
{
if(!Qf.empty()&&(Qf.size()>Qb.size()))//这里加了个数量判断就AC了
{
info now1=Qf.front();
Qf.pop();
for (int i=0; i<4; i++)
{
info v=now1;
v.s[i]--;
if(v.s[i]<49)
v.s[i]='9';
int num=change(v.s);
if(!pos[num])
{
v.step=now1.step+1;
pos[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(pos[num]==2)
return vis[num]+vis[change(now1.s)];
}
for (int i=0; i<4; i++)
{
info v=now1;
v.s[i]++;
if(v.s[i]>57)
v.s[i]='1';
int num=change(v.s);
if(!pos[num])
{
v.step=now1.step+1;
pos[num]=1;
vis[num]=v.step;
Qf.push(v);
}
else if(pos[num]==2)
return vis[num]+vis[change(now1.s)];
}
for (int i=0; i<3; i++)
{
info v=now1;
swap(v.s[i],v.s[i+1]);
int num=change(v.s);
if(!pos[num])
{
pos[num]=1;
v.step=now1.step+1;
vis[num]=v.step;
Qf.push(v);
}
else if(pos[num]==2)
return vis[num]+vis[change(now1.s)];
}
} if(!Qb.empty())
{
info now2=Qb.front();
Qb.pop();
for (int i=0; i<4; i++)
{
info v=now2;
v.s[i]--;
if(v.s[i]<49)
v.s[i]='9';
int num=change(v.s);
if(!pos[num])
{
v.step=now2.step+1;
pos[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(pos[num]==1)
return vis[num]+vis[change(now2.s)];
}
for (int i=0; i<4; i++)
{
info v=now2;
v.s[i]++;
if(v.s[i]>57)
v.s[i]='1';
int num=change(v.s);
if(!pos[num])
{
v.step=now2.step+1;
pos[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(pos[num]==1)
return vis[num]+vis[change(now2.s)];
}
for (int i=0; i<3; i++)
{
info v=now2;
swap(v.s[i],v.s[i+1]);
int num=change(v.s);
if(!pos[num])
{
v.step=now2.step+1;
pos[num]=2;
vis[num]=v.step;
Qb.push(v);
}
else if(pos[num]==1)
return vis[num]+vis[change(now2.s)];
}
}
}
}
int main(void)
{
int tcase;
scanf("%d",&tcase);
while (tcase--)
{
MM(pos);
MM(vis);
scanf("%s %s",ori.s,goal.s);
ori.step=0;
goal.step=0;
pos[change(ori.s)]=1;
pos[change(goal.s)]=2;
vis[change(ori.s)]=0;
vis[change(goal.s)]=0;
!strcmp(ori.s,goal.s)?puts("0"):printf("%d\n",T_bfs()+1);
}
return 0;
}

HDU——1195Open the Lock(双向BFS)的更多相关文章

  1. HDU 3085 Nightmare II 双向bfs 难度:2

    http://acm.hdu.edu.cn/showproblem.php?pid=3085 出的很好的双向bfs,卡时间,普通的bfs会超时 题意方面: 1. 可停留 2. ghost无视墙壁 3. ...

  2. HDU 1043 Eight(双向BFS+康托展开)

    http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用 ...

  3. HDU 3085 Nightmare Ⅱ(双向BFS)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 题目大意:给你一张n*m地图上,上面有有 ‘. ’:路 ‘X':墙 ’Z':鬼,每秒移动2步,可 ...

  4. HDU 6171 Admiral(双向BFS+队列)题解

    思路: 最大步骤有20,直接BFS会超时. 因为知道开始情况和结果所以可以用双向BFS,每个BFS规定最大步骤为10,这样相加肯定小于20.这里要保存每个状态搜索到的最小步骤,用Hash储存.当发现现 ...

  5. hdu 1043 Eight(双向bfs)

    题意:经典八数码问题 思路:双向bfs ps:还有a*算法(还不会)等解法. 代码: #include<iostream> #include<stdio.h> #include ...

  6. 2017多校第10场 HDU 6171 Admiral 双向BFS或者A*搜索

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6171 题意: 给你一个高度为6的塔形数组,你每次只能将0与他上下相邻的某个数交换,问最少交换多少次可以 ...

  7. ACM-BFS之Open the Lock——hdu1195(双向BFS)

    这道题的0基础版本号,暴力BFS及题目详情请戳:http://blog.csdn.net/lttree/article/details/24658031 上回书说道,要用双向BFS来尝试一下. 最终A ...

  8. HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

    题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出 ...

  9. HDU 2612 Find a way(双向bfs)

    题目代号:HDU 2612 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2612 Find a way Time Limit: 3000/1000 M ...

随机推荐

  1. MySQL存储过程(更新指定字段的数据)

    mysql存储过程示例: USE 数据库名称;DROP PROCEDURE IF EXISTS 数据库名称.存储过程名称;delimiter $$CREATE PROCEDURE 数据库名称.存储过程 ...

  2. C# 一维数组 冒泡排序

    假设有个三个杯子    一个杯子中有一个紫色的乒乓球  一个没有  一个有红色乒乓球    杯子不能动 怎么把紫色和红色的调换呢 主要是先把紫色的放到空的杯子   在把红的放到紫色原来的杯子   再把 ...

  3. vue 实现走马灯效果

    Part.1  问题 在写一个H5页面时遇到一个需求,头部公告需要滚动变换,需要实现一个走马灯效果 Part.2  实现 我的做法:利用 定时器 + CSS3 变换公告数组的顺序 从而实现走马灯效果 ...

  4. 后台返回平铺数据,如何转换成树形json并渲染树形结构,ant tree 异步加载

    如何后台返回对象数组(平铺式) 1.根据字段标识(板块)获取根节点 ### initTreeData(dataOrg){ var resultArr=dataOrg[0] var secArr=[]; ...

  5. nodeJS进程管理器pm2

    pm2是一个带有负载均衡功能的Node应用的进程管理器.当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载, PM2是完美的. PM2是开源的基于Nodejs的进程管 ...

  6. (4)JSTL的SQL标签库

    jstl的SQL标签库 SQL tag Library中的标签用来提供在 JSP 页面中可以与数据库进行交互的功能Database access标签库有以下6组标签来进行工作: <sql:set ...

  7. baidumap demo(一)

    覆盖物概述 地图上自定义的标注点和覆盖物我们统称为地图覆盖物.您可以通过定制BMKAnnotation和BMKOverlay来添加对应的标注点和覆盖物.地图覆盖物的设计遵循数据与View分离的原则,B ...

  8. 响应式web设计视图工具及插件总结----20150113

    响应式web设计可以说火不火是迟早的,下面就对于最开始的视口调试的方法汇总,希望有好的方法大家一起交流. 1.火狐:从Firefox升级到29.0之后就不直接支持Firesizer了. 先安装Add- ...

  9. [LUOGU] 3959 宝藏

    https://www.luogu.org/problemnew/show/P3959 注意到n非常小,考虑状压/搜索. 发现状压需要枚举起点,跑n次,一个问题是转移不可以以数字大小为阶段了,考虑用d ...

  10. python 删除大表数据

    #!/usr/bin/env python # encoding: utf-8 #@author: 东哥加油! #@file: del_tb_bigtable_statistic.py #@time: ...