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. RK3288开发过程中遇到的问题点和解决方法之Devices

    分区大小和“多用户支持” \device\rockchip\common\BoardConfig.mk BUILD_WITH_UMS ?= true改为BUILD_WITH_UMS ?= false ...

  2. linux 下node升级

    npm install -g n n stable 安装的路径: cd /usr/local/n/versions/node/10.15.3 修改环境变量 cd /etc sudo vim profi ...

  3. OutOfMemory

    查看图片格式,如果为PNG,可更改为jpg.图片会变小. 停止activity 当activity调用onStop()方法, activity不再可见,并且应该释放那些不再需要的所有资源.一旦acti ...

  4. Python相关机器学习

    Python机器学习库 Python的机器学习库汇总与梳理 机器学习之开源库大总结

  5. (十二)maven之nexus仓库的基本用法

    nexus仓库的基本用法 ① 启动nexus. 上一章有提到:https://www.cnblogs.com/NYfor2018/p/9079068.html ② 访问http://localhost ...

  6. Codeforces Round #290 (Div. 2) _B找矩形环的三种写法

    http://codeforces.com/contest/510/status/B 题目大意 给一个n*m  找有没有相同字母连起来的矩形串 第一种并查集 瞎搞一下 第一次的时候把val开成字符串了 ...

  7. Hibernate查询方式汇总

    Hibernate总的来说共有三种查询方式:HQL.QBC和SQL三种.但是细分可以有如下几种: 一.HQL查询方式    这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的 ...

  8. SpringMVC、Spring和Struts的区别

    http://www.cnblogs.com/hhx626/p/6010293.html 导读:近期做到的项目中,用到的框架师SSM(SpringMVC+Spring+Mybatis),那么在这之前用 ...

  9. SpringAOP 设计原理

    1.  设计原理 引入了,代理模式. java 程序执行流: 如果从虚拟机的角度看,整个程序的过程就是方法的调用,我们按照方法的执行顺序,将方法调用成一串. 在方法之间有着Join Point 连接点 ...

  10. Java生成固定长度的随机字符串(以大小写字母和数字)

    package org.jimmy.autosearch2019.test; import java.util.ArrayList; import java.util.Random; /** * @a ...