新手练习100题

Python挑战100题(31~33)

2019-08-12  本文已影响0人  YoYoYoo

31、取石子问题

题目:有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有两种不同的取法,
一是可以在任意的一堆中取走任意多的石子;二是可以在两堆中同时取走相同数量的石子。最后把石子全部取完者为胜者。
现在给出初始的两堆石子的数目a和b,如果轮到你先取,假设双方都采取最好的策略,问最后你是胜者还是败者。
如果你是胜者,输出Win,否则输出Loose。
例如,a=3,b=1, 则输出Win(你先在a中取一个,此时a=2,b=1,此时无论对方怎么取,你都能将所有石子都拿走).
参考答案:
威佐夫博弈
版权声明:本文为CSDN博主「ojshilu」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/ojshilu/article/details/16812173

a=3
b=1
if a<b:
    tmp=a
    a=b
    b=tmp
k=a-b
a=(int)(k*(1+5.0**0.5)/2.0);
if a==b:
    print('Loose')
else:
    print('Win')
平衡状态(奇异局势):

平衡状态的概念:
引入一个概念,平衡状态,又称作奇异局势。当面对这个局势时则会失败。任意非平衡态经过一次操作可以变为平衡态。每个玩家都会努力使自己抓完石子之后的局势为平衡,将这个平衡局势留给对方。因此,玩家A能够在初始为非平衡的游戏中取胜,玩家B能够在初始为平衡的游戏中取胜。

玩法三(2堆石子每次从一或两堆取一样数目的石子):

最后一个奇异局势是(0,0)。紧接着的奇异局势有(1,2),(3,5),(4,7),(6,10)......

现在把它们看成一个奇异局势组成的序列(0,0),(1,2),(3,5),(4,7),(6,10)......

奇异局势的判定:

我们会发现这个序列的规律,设序列第k个奇异局势元素为(Ak,Bk),k为自然数。那么,初始条件k=0时是,A0=B0=0,递推关系为下一个奇异局势的Ak是未在前面出现过的最小自然数,且Ak = Bk + k。

上面发现了奇异局势的递推公式,那么给出一个局势,如何判断其是否是奇异局势呢?

黄金分割数:

数学真奇妙,竟然发现,这个序列跟黄金分割数有关系。黄金分割数是2/(1+sqrt(5))=(sqrt(5)-1)/2,其小数约等于0.61803398875,其倒数是(1+sqrt(5))/2,约等于1.61803398875。

这个奇异局势的序列的通项公式可以表示为:

Ak = [k*(1+sqrt(5.0)/2]
Bk = Ak + k
其中k=0,1,2,...,n ,方括号表示int取整函数。

有了这个通项式子,逆向的,对于某一个局势,只需要判断其A是否是黄金分割数的某个k的倍数,然后再确认B是否等于A+k即可。

32、杨辉三角

题目:还记得中学时候学过的杨辉三角吗?具体的定义这里不再描述,你可以参考以下的图形:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
..............
先在给你一个正整数n,请你输出杨辉三角的前n层
注意:层数从1开始计数,每层数字之间用一个空格隔开,行尾不要有空格。
如n=2,则输出:
1
1 1
参考答案:

n= 6
L = [1]
i = 1
print(1)
while i < n:
    L.append(0)
    L = [L[j]+L[j-1] for j in range(len(L))]
    i += 1
    result = ' '.join([str(x) for x in L])
    print(result)

33、砝码问题Ⅱ

题目:有一组砝码,重量互不相等,分别为m1、m2、m3……mn;每种砝码的数量有无限个。
现要用这些砝码去称物体的重量,给你一个重量n,请你判断有给定的砝码能否称出重量n。
现在给你一个正整数列表w和一个正整数n,列表w中的第i个元素w[i]表示第i种砝码的重量,
n表示要你判断的重量。如果给定砝码能称出重量n,输出Yes,否则输出No。
例如,w=[2,5,11], n=9,则输出Yes(取两个2,一个5)。
参考答案:

''' 利用减法求解,通俗易懂,耗时短'''
w=[2,5,11]
n=9
flag = False

while n:
    n = min([n-x for x in w if n-x >= 0])
    if n == 0:
        flag = True
        break
    elif n <min(w):
        break

if flag:
    print('Yes')
else:
    print('No')
上一篇下一篇

猜你喜欢

热点阅读