谜题一 保持一致

谜题

假设有一大群人排队等待观看棒球比赛。他们都是主场球迷,每个人都戴着队帽,但不是所有人都用同一种戴法,有些人正着戴,有些人反着戴。

假定你是保安,只有在全组球迷帽子戴法一致时才能让他们进入球场,要么全部正着戴,要么全部反着戴。因为每个人对正戴和反戴的定义并不相同。因此你不能对他们说把帽子正着戴或反着戴,只能告诉他们转一下帽子。

举个栗子(我们用 F 表示正戴,B 表示反戴)

F F B B B F B B B F F B F

上面是一个13人的队伍,位置从0 ~ 12。你可以发出以下指令:

请 0 号位置的人转一下帽子,

请 1 号位置的人转一下帽子,

……

然后分别对5,9,10,12号位置的人发出同样的指令,总共要发出六次指令。

我们也可以发出这样的指令:

请 2~4 号位置的人转一下帽子,

请 6~8号位置的人转一下帽子,

请 11 号位置的人转一下帽子。

只需要 3 次指令。

我们的要求是让保安生成的命令数最少。难度更大的问题是:能否第一次沿着队伍就得正确答案呢?

算法

算法一 寻找想法相同的连续人员

计算正戴区间和反戴区间的个数, 区间数更少的即是我们要反转的帽子区间。

def pleaseconform(caps):

section = [] # 统计各区间的列表

start = 0

Fnum = 0 # 正戴区间数

Bnum = 0 # 反戴区间数

for i in range(1,len(caps)):

if caps[start] != caps[i]: # 标志着新区间的产生

section.append([start , i-1 ,caps[start]])

if caps[start]=='F':

Fnum += 1

else:

Bnum += 1

start = i

section.append([start,len(caps)-1,caps[start]]) # 6~13行代码未添加最后一个区间,这行代码用于添加最后一个区间

if caps[start]=='F':

Fnum += 1

else:

Bnum +=1

if Fnum>Bnum :

flag = 'B'

else:

flag = 'F'

for t in section:

if t[2]==flag:

if(t[0] == t[1]):

print("请"+str(t[0])+"号位置的人反转帽子")

else:

print("请"+str(t[0])+"到"+str(t[1])+"的人反转帽子")

caps = ['F','F','B','B','B','F','B','B','B','F','F','B','F']

pleaseconform(caps)

"""

Output:

请2到4的人反转帽子

请6到8的人反转帽子

请11号位置的人反转帽子

"""

我们注意到算法一的核心代码 6~13 行未添加最后一个区间,因此我们要再添加代码来完善算法,显得过于繁琐。实际上,我们只需要在 caps 列表添加一个其他元素如’M’,就可以消除掉这种情况。

# 代码优化

def pleaseconform(caps):

caps.append('M')

section = []

start = 0

Fnum = 0

Bnum = 0

for i in range(1,len(caps)):

if caps[start] != caps[i]:

section.append([start , i-1 ,caps[start]])

if caps[start]=='F':

Fnum += 1

else:

Bnum += 1

start = i

if Fnum>Bnum :

flag = 'B'

else:

flag = 'F'

for t in section:

if t[2]==flag:

if(t[0] == t[1]):

print("请"+str(t[0])+"号位置的人反转帽子")

else:

print("请"+str(t[0])+"到"+str(t[1])+"的人反转帽子")

caps = ['F','F','B','B','B','F','B','B','B','F','F','B','F']

pleaseconform(caps)

"""

Output:

请2到4的人反转帽子

请6到8的人反转帽子

请11号位置的人反转帽子

"""

算法二 单遍算法one pass

通过观察,实际上我们只需要通过 caps 列表中第一只帽子的方向,就可以得出我们需要反转的是正戴区间还是反戴区间。因为第一只帽子方向区间的个数一定大于等于另一方向的区间数。基于这一观察,能够实现一个one pass 算法。

# one pass

def pleaseconformonepass(caps):

caps.append(caps[0])

for i in range(1,len(caps)):

if(caps[i] != caps[i-1]):

if(caps[i] != caps[0]):

print("请"+str(i)+"号位置到")

else:

print(str(i-1)+"号位置的人反转帽子")

pleaseconformonepass(caps)

"""

Output:

请2号位置到

4号位置的人反转帽子

请6号位置到

8号位置的人反转帽子

请11号位置到

11号位置的人反转帽子

"""

谜题背后

这道谜题背后的出发点是数据压缩。向同一方向的人发出的命令信息是相同的,可以被压缩为一组较少的命令,其中每一条命令指挥一组连续的人。

谜题拓展

数据压缩有多种实现方式,在思路上接近于这道习题的一种算法叫做游程编码。举一个最简单的例子最容易描述,假设有以下字符串:

WWWWWWWWWWWWWBBWWWWWWWWWWWWBBBBB

使用游程编码算法,我们可以把上述字符串压缩为一个由数字和字符构成的字符串:

13W2B12W5B

游程解码算法就是把’ 13W2B12W5B ‘解压为原始字符串的过程。

现代计算机的压缩工具,便是利用了这种思想相关的算法。

以下是游程编码解码的具体实现:

def youcengbianma(string):

start=0

newstring = ''

for i in range(1,len(string)):

if(string[start]!=string[i]):

newstring += str(i-start)

newstring += string[start]

start=i

newstring += str(i-start+1)

newstring += string[start]

return newstring

print(youcengbianma("wwweeewwwweeffeee"))

"""

Output:

3w3e4w2e2f3e

"""

def youcengjiema(string):

num = ''

newstring = ''

for i in range(0,len(string)):

if(not string[i].isalpha()): # isalpha() 如果是字母字符,返回true

num += string[i]

else:

for j in range(0,int(num)):

newstring += string[i]

num = ''

return newstring

print(youcengjiema("3w3e4w2e2f3e")

"""

Output:

wwweeewwwweeffeee

"""

原文链接:https://www.cnblogs.com/

本站声明:网站内容来源于网络,如有侵权,请联系我们,我们将及时处理。

用python解算法谜题_【编程的乐趣-用python解算法谜题系列】谜题一 保持一致相关推荐

  1. 用python解算法谜题_编程的乐趣 用Python解算法谜题

    这是一本介绍通过解决复杂谜题来学习编程的书,书中的代码用Python语言编写.与以往的编程书不同,本书将对代码功能的理解与编程语言语法和语义的理解分离开来,从解每个谜题开始,先给出解谜题的算法,随后用 ...

  2. python女神讲师视频教程_阿里巴巴讲师高赞Python全集视频教程,这就是你需要的...

    Python是世界上功能最多,功能最强大的编程语言之一.通过Python,可以编写自己的应用程序,创建游戏,设计算法,甚至编程机器人.而且Python的热度现在一直高居不下,比如,完成同一个任务,C语 ...

  3. 阿里云python自测答案_阿里云技能测试python初级中级高级

    简介 偶尔发现,阿里云-开发者社区,里竟然有技能测试平台 覆盖知识面也较多 初级(65) 涉及知识点:Python语言的基本特性.编程环境.语法基础.数据结构,了解Python的网络编程与Web开发, ...

  4. python新手入门教程思路-Python新手入门教程_教你怎么用Python做数据分析

    Python新手入门教程_教你怎么用Python做数据分析 跟大家讲了这么多期的Python教程,有小伙伴在学Python新手教程的时候说学Python比较复杂的地方就是资料太多了,比较复杂.很多网上 ...

  5. python跳舞的线_舞蹈链(Dance Link X)算法详解及python实现

    这两天打算做个数独玩玩,查了一下解数独最好的算法叫舞蹈链:Dance Link X 该算法主要是解决精确覆盖问题:比如有个集合X,以及其若干子集的集合Y,要求出一个Y的子集Y*,能够恰好分割X. 举个 ...

  6. python路线寻优_基于DEAP库的Python进化算法从入门到入土 --(四)遗传算法的改进...

    前言 前面一节我们尝试了用GA求解TSP问题,简单遗传算法总是不能很好收敛到一个较优的解,在用时和求解精度上都被贪心算法吊打.在末尾我们总结了三个可能的改进方向,这次我们想要沿着这三个方向试着改进简单 ...

  7. c语言python零基础教学_编程零基础应当如何开始学习 Python?附教程

    零基础学编程,用python入门是个不错的选择,虽然国内基本上还是以c语言作为入门开发语言,但在国外,已经有很多的学校使用python作为入门编程语言.此外,python在机器学习,人工智能领域也非常 ...

  8. c语言python零基础教学_编程零基础应当如何开始学习 Python?

    目录 1.学习了解Python的基础知识. 2.安装Python,边学边练. 3.收集资料,作为练习指引. 4.确定学习方向,项目练手. 5.学习过程中要注意多练.多问! 编程零基础选择Python开 ...

  9. python游戏开发工程师_史上最全Python课程整理——我是如何从编程小白到Python研发工程师的...

    从编程小白,到Python研发工程师,需要多久呢? 答案就是:91门课,450个小时. 听起来似乎难以实现,但其实如果每天抽出八小时学习,两个月的时间,就能由编程小白转变成为Python工程师,听起来 ...

  10. python清单全套教程_编程最经典的一份python学习清单,零基础都可以学会的教程...

    站在风口上,猪都能飞起来.人工智能风口,让Pyhon这门胶水语言转变成非常火的网红语言. 编程功力深厚的程序员花一两个星期就能上手Python,而一些新手程序员花几个月就可以上手. 学编程,用Pyth ...

最新文章

  1. Easy3D:一个轻量级、易用、高效的C++库,用于处理和渲染3D数据
  2. Checkly如何借助Terraform实现零宕机部署
  3. 记忆化搜素,和递推法
  4. 软件开发了10年,迷茫了
  5. FutureTask isDone 返回 false
  6. 十二、一篇文章帮助你快速读懂MySQL索引(B树、B+树详解)
  7. ThinkPHP-保存生成的二维码
  8. STM32工作笔记0043---什么是漏源电压,栅源电压
  9. C++ 从入门到入土(English Version) Section 2:Computer Memory and Number Systems
  10. 2020年互联网大厂中秋礼盒PK!看看你的礼盒怎么样
  11. 网吧版XP系统制作与优化终极版(转)
  12. python爬虫网络库下载_Python3 DHT 网络磁力种子爬虫
  13. 台式计算机连接投影仪无信号,acer投影仪显示无信号?电脑开机显示器无信号?投影仪无信号输入的解决办法是什么?...
  14. 数字麦克风PDM信号采集与STM32 I2S接口应用(三)
  15. Lipschitz条件
  16. 生成模型与判别模型详解
  17. 运维学习之lvm(逻辑卷管理)
  18. 【FPGA教程案例10】基于Verilog的复数乘法器设计与实现
  19. 中国教师研修网计算机培训心得体会,教师网络培训学习心得体会最新5篇精选...
  20. Glove模型的原理与代码

热门文章

  1. Dubbo-admin无法显示Group分组信息
  2. 开源框架Struts:FormBean滴那些事儿
  3. Treeview动态添加用户控件 取值和传值(第二种样式)
  4. 绝对经典的滑轮新闻显示(javascript+css)
  5. 28.MySQL Variables
  6. 18. PHP 表单验证
  7. 第004讲 浮动窗口 表单及表单控件
  8. [Python3] 010 字符串:给你们看看我的内置方法 第二弹
  9. Flume案例之采集特定目录的数据到HDFS
  10. 超低静态电流LDO稳压器选择要点