算法笔记(持续更新)

1. 巴什博弈的“变种”

1.1 描述

有一堆总数为M的物品,A,B两名玩家轮流从中拿取物品。规定拿取物品的数目必须是1,3,7和8,每个玩家都必须拿,A先拿,然后B再拿,两人交替拿取物品,直至取完所有的物品,规定拿到最后一个物品的一方失败。

1.2 输入

要求首先输入一个整数n(0<n<100),代表有几组测试,然后是n个整数,每个整数占一行,表示有M个物品,0<M<10000

1.3 输出

要求输出n行,表示A的输赢,输了就输出0,赢了就输出1

1.4 实现思路

1.4.1 算法分析

先假设以下总数M,
总数为1,A先拿,A必输。
总数为2,A先拿,A拿1,A必赢。
总数为3,A先拿,若A拿3,A必输。若A拿1,则B必拿1,随后A拿1,A必输。
总数为4,A先拿,若A拿3,则A必赢。
总数为5,A先拿,若A拿1,则B必定也拿1,随后最后一个也是A拿的,A必输。
总数为6,A先拿,若A拿1,剩余5个,对于B来说在5个中无论拿多少都是必输,故A必赢。
总数为7,A先拿,若A拿1,则剩余6个,对于B来说在6个中只需要拿1个,B就可以赢了,故A必输。
总数为8,A先拿,若A拿1,则剩余7个,对于B来说在7个中,无论是拿1个,还是3个,还是7个,都必输。故A必赢。

通过以上推理可以知道,如果A想要赢,无论是A拿几个,在B开始拿的时候,保证物品的总数符合无论B拿多少,都是必输的即可,这样A就可以赢了。在前8次中,只有总数为 2,4,6,8的时候,A才会赢。
所以dp[M] = not dp[j - 1] or not dp[j - 3] or not dp[j - 7] or not dp[j - 8]

1.4.2 代码实现

def myBashGame():
    # 创建字典,将总数和A的输赢分别用k,v表示
    dp = {
   k: True if k % 2 == 0 else False for k in range(1, 9)}
    n = int(input())
    # sum_goods = 0
    for i in range(n):
        sum_goods = int(input())
        if sum_goods > len(dp):
            for j in range(9, sum_goods + 1):
                # A 先拿,随后B拿,即B拿的时候,dp[j-x] 中不包含 dp[2] dp[4] dp[6] dp[8] 的时候,B必输,A必赢
                dp[j] = not dp[j - 1] or not dp[j - 3] or not dp[j - 7] or not dp[j - 8]
        print(1 if dp[sum_goods] else 0)

2. 最小因子

2.1 描述

给一个整数n,将它拆分成他所有最小因子(最小因子大于1)的连成形式,同时要保证小的因子在前面。如:n = 10 则输出2*5=10

2.2 输入

要求输入包含多组数据,每组包含一个整数n,1<n<=1000000

2.3输出

每组输出分解的结果。

2.4 实现思路

2.4.1 算法分析

最小因子大于1,即最小因子为2,则用n对2求余,若余数为0,则说明2是该数的因子,然后用n整除2,得到m,判断m对2求余,余数也是0,若也是0,则用m整除2,得到数以此类推,直至结果小于1.
若m对2求余,余数不为0,说明2不是该数的因子,则将最小因子+1,即3,然后对3求余,判断余数,以此类推。最后格式化输出即可。

2.4.2 代码实现

def myMinFactor():
    while True:
        try:
            num = int(input())
            temp_num = num
            temp_factor = []
            min_factor = 2
            while temp_num > 1:
                while temp_num % min_factor == 0:
                    temp_factor.append(min_factor)
                    temp_num //= min_factor
                min_factor += 1
            for i in range(len(temp_factor)):
                if i == len(temp_factor) - 1:
                    print("{}={}".format(str(temp_facto
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值