当前位置: 首页 > news >正文

算法学习之路|聪明的打字员

Description
阿兰是某机密部门的打字员,她现在接到一个任务:需要在一天之内输入几百个长度固定为6的密码。当然,她希望输入的过程中敲击键盘的总次数越少越好。
不幸的是,出于保密的需要,该部门用于输入密码的键盘是特殊设计的,键盘上没有数字键,而只有以下六个键:Swap0, Swap1, Up, Down, Left, Right,为了说明这6个键的作用,我们先定义录入区的6个位置的编号,从左至右依次为1,2,3,4,5,6。下面列出每个键的作用:
Swap0:按Swap0,光标位置不变,将光标所在位置的数字与录入区的1号位置的数字(左起第一个数字)交换。如果光标已经处在录入区的1号位置,则按Swap0键之后,录入区的数字不变;
Swap1:按Swap1,光标位置不变,将光标所在位置的数字与录入区的6号位置的数字(左起第六个数字)交换。如果光标已经处在录入区的6号位置,则按Swap1键之后,录入区的数字不变;
Up:按Up,光标位置不变,将光标所在位置的数字加1(除非该数字是9)。例如,如果光标所在位置的数字为2,按Up之后,该处的数字变为3;如果该处数字为9,则按Up之后,数字不变,光标位置也不变;
Down:按Down,光标位置不变,将光标所在位置的数字减1(除非该数字是0),如果该处数字为0,则按Down之后,数字不变,光标位置也不变;
Left:按Left,光标左移一个位置,如果光标已经在录入区的1号位置(左起第一个位置)上,则光标不动;
Right:按Right,光标右移一个位置,如果光标已经在录入区的6号位置(左起第六个位置)上,则光标不动。
当然,为了使这样的键盘发挥作用,每次录入密码之前,录入区总会随机出现一个长度为6的初始密码,而且光标固定出现在1号位置上。当巧妙地使用上述六个特殊键之后,可以得到目标密码,这时光标允许停在任何一个位置。
现在,阿兰需要你的帮助,编写一个程序,求出录入一个密码需要的最少的击键次数。
Input
仅一行,含有两个长度为6的数,前者为初始密码,后者为目标密码,两个密码之间用一个空格隔开。
Output
仅一行,含有一个正整数,为最少需要的击键次数。
Sample Input
123456 654321
Sample Output
11
Source
Noi 01

题目分析:在状态的最后一位补一个记录光标然后BFS,两个剪枝
1.Up,Down只有在当前位和目标位不同时才进行,这是显然的
2.Left,Right时只有中间四位和目标位相同时才进行,因为移动光标不会影响数字的状态,因此数字位不同时,只移动光标没有什么意义
字符串用map哈希,g++跑了两个1000ms,然而c++ 300+过

# -*- coding: utf-8 -*-
import copy
queue=[]#0是队列的front
found=[]#确保搜索一次,即变来变去不会变回原来的样子
class node:
    def __init__(self,string,count):
        self.s=string #s[0]为当前光标位置
        self.c=count
def bfs(endstr):

    while len(queue)!=0:
        cur=queue[0]#current
        del queue[0]
        if cur.s[1:]==endstr:
            return cur.c
        #Swap6
        c=copy.deepcopy(cur)#防止原node变化
        print c.s
        print c.s[0]
        if c.s[0]!=6 and c.s[c.s[0]]!=endstr[c.s[0]-1]:#剪枝
            c.s[c.s[0]],c.s[6]=c.s[6],c.s[c.s[0]]
            c.c+=1
            if c.s not in found:
                found.append(c.s)
                queue.append(c)

        #Swap1
        c = copy.deepcopy(cur)
        if c.s[0] != 1 and c.s[c.s[0]]!=endstr[c.s[0]-1]:
            c.s[c.s[0]],c.s[1]=c.s[1],c.s[c.s[0]]
            c.c+=1
            if c.s not in found:
                found.append(c.s)
                queue.append(c)

        #up
        c = copy.deepcopy(cur)
        if c.s[c.s[0]]!=endstr[c.s[0]-1] and c.s[c.s[0]]!=9:#当前位和目标位不同时才进行
            #解释:
            #destion:1 2 4---4 2 4 p=2,即使[0],[2]互换,也多了一步,毫不起作用
            #destion:1 2 4---3 2 4 p=2,[0][2]互换,多了5步
            c.s[c.s[0]]+=1
            c.c+=1
            if c.s not in found:
                found.append(c.s)
                queue.append(c)

        # down
        c = copy.deepcopy(cur)
        if c.s[c.s[0]] != endstr[c.s[0]-1] and c.s[c.s[0]]!=0:#剪枝
            c = copy.deepcopy(cur)
            c.s[c.s[0]]-=1
            c.c+=1
            if c.s not in found:
                found.append(c.s)
                queue.append(c)

        #left
        c = copy.deepcopy(cur)
        if c.s[c.s[0]] == endstr[c.s[0]-1] and c.s[0]!=1:#剪枝
            #只有当前位和目标位相同时才进行,因为移动光标不会影响数字的状态,
            # 因此数字位不同时,只移动光标没有什么意义
            c.s[0]-=1
            c.c+=1
            if c.s not in found:
                found.append(c.s)
                queue.append(c)
        #right
        c = copy.deepcopy(cur)
        if c.s[c.s[0]] == endstr[c.s[0]-1] and c.s[0]!=6:#剪枝
            c.s[0]+=1
            c.c+=1
            if c.s not in found:
                found.append(c.s)
                queue.append(c)

queue.append(node([1,1,2,3,4,5,6],0))
print bfs([6,5,4,3,2,1])

相关文章:

  • [学习笔记—Objective-C]《Objective-C-基础教程 第2版》第二章~第七章
  • MongoDB入门(二)——MongoDB下载与安装
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • centos7设置静态IP
  • 64位x86的函数调用栈布局
  • 纯文本配置还是注册表
  • “你的优势是什么?
  • 记录项目代码迁移后,UI测试框架的搭建(配置文件的修改、测试脚本试运行)...
  • QComboBox 树形视图选择
  • 用户28万、营收超1亿,《生化危机》给VR游戏做了个好榜样
  • 验证数据过程中碰到的问题记录
  • Python--多进程
  • IE安全系列之:中流砥柱(I)—Jscript 5处理浅析
  • python一条语句分析几个常用函数和概念
  • 使用strtok_s函数从一个字符串中分离出单词
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【跃迁之路】【735天】程序员高效学习方法论探索系列(实验阶段492-2019.2.25)...
  • CAP 一致性协议及应用解析
  • css属性的继承、初识值、计算值、当前值、应用值
  • extract-text-webpack-plugin用法
  • k8s 面向应用开发者的基础命令
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • SQLServer之索引简介
  • webpack项目中使用grunt监听文件变动自动打包编译
  • Web设计流程优化:网页效果图设计新思路
  • 阿里云Kubernetes容器服务上体验Knative
  • 构建工具 - 收藏集 - 掘金
  • 类orAPI - 收藏集 - 掘金
  • 两列自适应布局方案整理
  • 无服务器化是企业 IT 架构的未来吗?
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 如何通过报表单元格右键控制报表跳转到不同链接地址 ...
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • "无招胜有招"nbsp;史上最全的互…
  • #我与Java虚拟机的故事#连载08:书读百遍其义自见
  • #周末课堂# 【Linux + JVM + Mysql高级性能优化班】(火热报名中~~~)
  • (11)MSP430F5529 定时器B
  • (c语言)strcpy函数用法
  • (独孤九剑)--文件系统
  • (十二)devops持续集成开发——jenkins的全局工具配置之sonar qube环境安装及配置
  • (终章)[图像识别]13.OpenCV案例 自定义训练集分类器物体检测
  • ... 是什么 ?... 有什么用处?
  • .Family_物联网
  • .mysql secret在哪_MySQL如何使用索引
  • .NET MVC第三章、三种传值方式
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • @javax.ws.rs Webservice注解
  • [ C++ ] STL_list 使用及其模拟实现
  • [AIGC codze] Kafka 的 rebalance 机制
  • [ASP.NET 控件实作 Day7] 设定工具箱的控件图标
  • [BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)
  • [BZOJ1010] [HNOI2008] 玩具装箱toy (斜率优化)
  • [codeforces] 25E Test || hash
  • [dart学习]第四篇:函数
  • [ffmpeg] x264 配置参数解析