【每周一坑】田忌赛马
本周的题目取自著名的历史典故:田忌赛马
背景资料如下
田忌经常与齐国众公子赛马,设重金赌注。田忌的上宾孙膑发现他们的马脚力都差不多,马分为上、中、下三等,于是对田忌说:“您只管下大赌注,我能让您取胜。”田忌相信并答应了他,与齐王和各位公子用千金来赌注。比赛即将开始,孙膑说:“现在用您的下等马对付他们的上等马,用您的上等马对付他们的中等马,用您的中等马对付他们的下等马。”已经比了三场比赛,田忌一场败而两场胜,最终赢得齐王的千金赌注。
现在我们将齐王的马抽象为一个列表 [3,6,9]
,田忌的马抽象为另一个列表 [2,5,8]
,分别代表各自的下、中、上等马。设计一个函数 race()
,将两个列表作为参数传递给 race()
,将背景资料的策略抽象为代码使田忌赢得比赛,函数返回每轮对阵情况,结果示例:
def race(qiwang,tianji): ''' >>> race([3,6,9],[2,5,8]) [(9,2),(6,8),(3,5)] '''
附加题:
1、如果你是某公子手下的谋士,已知同级别中己方的马优于田忌的马,事先不知道对方派遣顺序,不过可以根据上一轮对方的派出的马匹制定本轮的选择。为公子制定一种派遣策略,使赢得比赛的几率最大。
提示:田忌的策略可用 random 确定
import random g = [3,6,9] t = [2,5,8]
# 田忌的策略
def tianji_s(): return random.shuffle(t)
# 公子的策略
def gongzi_s(): ''' your code here '''
# 至少 1000 次测试
for i in range(1000):
''' your code here '''
2、现在将马分为 优、上、中、下、劣 五等,五局三胜制,抽象为列表[2,4,6,8,10]
与 [1,3,5,7,9]
,其他条件不变,计算出田忌有多少种赢得比赛的可能。
期待各位同学对于本周题目的代码提交。
提交代码可以使用 paste.ubuntu.com 或 codeshare.io 等代码分享网站,只需将代码复制上去保存,即可获得一个分享地址,非常方便。
往期问题可通过公众号菜单栏“课外辅导”栏目中进入查看。
【乒乓数】 解答
乒乓序列从1开始计数,并且始终向上或向下计数。在元素k处,如果k是7的倍数或包含数字7,方向将切换,定义一个函数 pingpong ,传入一个正整数参数 n ,返回第 n 个乒乓数。
def pingpong(n,k=7): '''传入一个正整数参数 n 和特殊数 k,返回第 n 个乒乓数 n - 第 n 个乒乓数 k - 给定的特殊数,默认为 7 ''' # count 计数,随着循环增加 # num 为 第 count 个数时的乒乓数 # status 为增或减状态,在 正负 1 之间切换,默认为 1 count,num,status = 1,1,1 # 断言 n,k 为正整数,否则抛出错误 assert isinstance(n,int) and n > 0 ,'input error' assert isinstance(k,int) and k > 0 ,'input error' while count < n:
# 判断切换条件 if str(k) in str(count) or count % k == 0: status *= -1 # 累加或累减 num += status count += 1 return num
这道题的关键在于预设一个递增或递减的状态,结合 if 判断下一次运算是加 1 还是减 1 ,很多同学都采取了相同的计算原理,写出了比较简洁的代码,参考:
@皮特尔:https://codeshare.io/5vAV3l
@bolin:http://paste.ubuntu.com/24332853/
@LDJ:https://github.com/NyanCat12/CrossinWeekly/blob/master/20170407/pingpong.py
@Nicked:https://github.com/nicktimebreak/CrossinWeekly/blob/master/pingpong.py
另外 @徐大龙 同学使用了 generator 的方式计算,也值得参考:
https://github.com/PeytonXu/learn-python/blob/master/cases/pingpong/pingpong.py