Description
现在一个紧急的任务是打开一个密码锁。密码由四位数字组成,每个数字从 1 到 9 进行编号。每次可以对任何数字加 1 或减 1。当将9加 1 时,数字将变为1,当1减 1 的时,数字将变为9。您也可以与邻居交换数字,每一个行动记做一步。现在你的任务是使用最小的步骤来打开锁。
注意:最左边的数字不是最右边数字的邻居。
Input
第一行输入四位数字,表示密码锁的初始状态。第二行输入四位数字,表示开锁的密码。
Output
输出一个整数,表示最小步骤。
Sample Input 1
1234
2144
Sample Output 1
2

这道题一看,似乎不该用搜索。

又一想,这种题目也只能使用bfs来完成。

但是怎么打标记?

普通的一维的vis数组已经无法满足这道题目的需求了,应该怎么解决?

再认真一看,它的起始和重点都是4个数字构成,我们可以把由4个数字组成的一组密码记为一种状态,即:

当密码为abcd时,对应的标记就应该记为vis[a][b][c][d]=1;

简单来说,就是通过四维数组,完成打标记这一步。

接下来的操作就是最基本的bfs,代码随便敲下来就可以了。

按照题意,每个密码能够进行的拓展操作分别为:

每一位加/减一位构成的新密码;

分别交换第1,2/2,3/3,4位构成的新密码;

然后判断,如果是没有打标记的,打进队列然后打标记即可。

AC代码:

#include<bits/stdc++.h>
using namespace std; struct node
{
int aa[4];
int t;
node(){};
node(int a0,int a1,int a2,int a3,int t_)
{
aa[0]=a0;
aa[1]=a1;
aa[2]=a2;
aa[3]=a3;
t=t_;
}
}mb;//mb:目标
bool x[10][10][10][10];
queue<node> qu; bool in(node a)
{
if(a.aa[0]==mb.aa[0]&&a.aa[1]==mb.aa[1]&&a.aa[2]==mb.aa[2]&&a.aa[3]==mb.aa[3])return false;
else return true;
} int bfs(int a,int b,int c,int d)
{
qu.push(node(a,b,c,d,0));
x[a][b][c][d]=1;
while(in(qu.front())&&!qu.empty())
{
node now=qu.front();
qu.pop(); if(!x[now.aa[1]][now.aa[0]][now.aa[2]][now.aa[3]])
{
qu.push(node(now.aa[1],now.aa[0],now.aa[2],now.aa[3],now.t+1));
x[now.aa[1]][now.aa[0]][now.aa[2]][now.aa[3]]=1;
}
//a,b,c,d->b,a,c,d if(!x[now.aa[0]][now.aa[2]][now.aa[1]][now.aa[3]])
{
qu.push(node(now.aa[0],now.aa[2],now.aa[1],now.aa[3],now.t+1));
x[now.aa[0]][now.aa[2]][now.aa[1]][now.aa[3]]=1;
}
//a,b,c,d->a,c,b,d if(!x[now.aa[0]][now.aa[1]][now.aa[3]][now.aa[2]])
{
qu.push(node(now.aa[0],now.aa[1],now.aa[3],now.aa[2],now.t+1));
x[now.aa[0]][now.aa[1]][now.aa[3]][now.aa[2]]=1;
}
//a,b,c,d->a,b,d,c
//因为a和d 不能直接交换所以就只有这三种情况
for(int i=0;i<4;i++)
{
node nxt=now; nxt.aa[i]++;
nxt.t++; if(nxt.aa[i]==10)nxt.aa[i]=1; if(!x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]])
{
qu.push(nxt);
x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]]=1;
} } for(int i=0;i<4;i++)
{
node nxt=now; nxt.aa[i]--;
nxt.t++; if(nxt.aa[i]==0)nxt.aa[i]=9; if(!x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]])
{
qu.push(nxt);
x[nxt.aa[0]][nxt.aa[1]][nxt.aa[2]][nxt.aa[3]]=1;
} }
} return qu.front().t; } int main()
{
int st,ed;
cin>>st>>ed; mb=node(ed/1000,ed%1000/100,ed%100/10,ed%10,0); cout<<bfs(st/1000,st%1000/100,st%100/10,st%10)<<endl;
return 0;
}

ov.

【bfs】密码锁-C++的更多相关文章

  1. 计蒜客 密码锁(BFS)

    https://www.jisuanke.com/course/1797/121114 Description 现在一个紧急的任务是打开一个密码锁.密码由四位数字组成,每个数字从 1 到 9 进行编号 ...

  2. 算法提高 密码锁 (BFS)

    问题描述 你获得了一个据说是古代玛雅人制作的箱子.你非常想打开箱子看看里面有什么东西,但是不幸的是,正如所有故事里一样,神秘的箱子出现的时候总是会挂着神秘的锁. 这个锁上面看起来有  N  个数字,它 ...

  3. hdu.1226.超级密码(bfs)

    超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  4. 超级密码(bfs)

    超级密码 Time Limit : 20000/10000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

  5. 超级密码 hdu1226 bfs

    超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  6. hdu 1226 bfs+余数判重+大数取余

    题目: 超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  7. HDU-1226 超级密码 (BFS+剪枝)

    Problem Description Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:密 码是一个C进 ...

  8. hdu1226 超级密码 (BFS,里面用了大数取余原理)

    Problem Description Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息: 密码是一个C进 ...

  9. HDU1226:超级密码(BFS)

    Problem Description Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息: 密码是一个C进 ...

随机推荐

  1. PHP命名空间和自动加载初探

    参考资料: PHP手册-语言参考:http://php.net/manual/zh/language.namespaces.php   概要: 1. 声明了命名空间之后,下面的const, funct ...

  2. SqlServer & Windows 可更新订阅立即更新启用分布式事务协调器(MSDTC)

    原文:SqlServer & Windows 可更新订阅立即更新启用分布式事务协调器(MSDTC) 在可更新订阅中,在订阅设置更新方法,将 "排队更新" 设置为 " ...

  3. LINQ查询表达式---------join子句

    LINQ查询表达式---------join子句 join 子句接受两个源序列作为输入. 每个序列中的元素都必须是可以与另一个序列中的相应属性进行比较的属性,或者包含一个这样的属性. join子句使用 ...

  4. ORACLE 11.2.0.4 Single To Single Data Guard 安装 physical standby

    [root@ORACLE ~]# su - oracle [oracle@ORACLE ~]$ sqlplus / as sysdba . 查看主库归档模式: SQL> select log_m ...

  5. .NET重思(三)-数组列表与数组的区别,栈集合和队列结合的区别

    数组列表和数组十分相似,区别在于数组列表的容量是可以动态变化的,而数组的容量是固定的.数组即Array类,数组列表即ArrayList类,两者十分相似.不过,Array类在System命名空间下,Ar ...

  6. Js 动态插入css js文件

    function loadjscssfile(filename,filetype){ var file, //动态插入的文件 doc = document; if(filetype == " ...

  7. 使用VS2012开发基于Office 2013的AddIn程序

    默认VS2012开发的Office Add是基于2010的,如下所示: 如果你机器上安装的Office版本是2013,那么使用VS2012创建的工程是无法运行的,弹出如下的错误: 那么此时怎么办呢?将 ...

  8. 缩放手势 ScaleGestureDetector 源码解析,这一篇就够了

    其实在我们日常的编程中,对于缩放手势的使用并不是很经常,这一手势主要是用在图片浏览方面,比如下方例子.但是(敲重点),作为 Android 入门的基础来说,学习 ScaleGestureDetecto ...

  9. 【Flink】Flink 底层RPC框架分析

    1. 前言 对于Flink中各个组件(JobMaster.TaskManager.Dispatcher等),其底层RPC框架基于Akka实现,本文着重分析Flink中的Rpc框架实现机制及梳理其通信流 ...

  10. 获取Spring中的Bean

    1.Utils工具类 package com.xxx.common.helper; import org.springframework.beans.BeansException; import or ...