小U的防御挑战 | 豆包MarsCode AI刷题

224 阅读5分钟

一、小U的防御挑战

问题描述

小U最近沉迷于一款冒险游戏,在闯关过程中,他通过击败小兵获得了防御宝石,每个防御宝石的价值为 aiai​。经过一番激战,小U终于遇到了关底的boss,这个boss拥有攻击宝石,每颗攻击宝石的价值为 bibi​。小U想知道他手中的防御宝石是否能够抵抗住boss的攻击。
小U的防御成功条件是:所有防御宝石的乘积 ∏i=1nai∏i=1n​ai​ 可以被所有攻击宝石的乘积 ∏i=1mbi∏i=1m​bi​ 整除。你能帮小U判断他是否能够抵抗住boss的攻击吗?

测试样例

样例1

输入:n = 2 ,m = 5 ,arrayn = [10, 12] ,arraym = [2, 3, 5, 2, 1]
输出:'yes'

样例2

输入:n = 4 ,m = 5 ,arrayn = [7, 2, 5, 3] ,arraym = [2, 4, 5, 6, 1]
输出:'no'

样例3

输入:n = 3 ,m = 4 ,arrayn = [6, 3, 9] ,arraym = [2, 3, 4, 1]
输出:'no'

二、解题思路

(1)问题理解

小U在游戏中通过击败小兵获得了防御宝石,每个防御宝石有一个价值 ai​。同时,他遇到了关底的boss,这个boss拥有攻击宝石,每颗攻击宝石的价值为 bi​。小U需要判断他手中的防御宝石是否能够抵抗住boss的攻击。防御成功的条件是:所有防御宝石的乘积 ∏i=1n​ai​ 可以被所有攻击宝石的乘积 ∏i=1m​bi​ 整除。

(2)数据结构的选择逻辑

为了判断防御宝石的乘积是否能被攻击宝石的乘积整除,我们可以利用质因数分解的方法。质因数分解是一种将一个正整数分解为若干个质数的乘积的方法。通过分解质因数,我们可以将乘积的整除问题转化为质因数的比较问题。 具体来说,对于每个防御宝石和攻击宝石的值,我们可以将其分解为质因数,并统计每个质因数的出现次数。然后,我们可以比较防御宝石和攻击宝石的质因数统计结果,判断防御宝石的乘积是否能被攻击宝石的乘积整除。

(3)算法步骤

1.分解质因数

对于每个防御宝石和攻击宝石的值,分解其质因数,并统计每个质因数的出现次数。例如,数字12可以分解为2^2 * 3^1。

2.统计质因数

对于防御宝石的乘积,统计每个质因数的总出现次数。对于攻击宝石的乘积,统计每个质因数的总出现次数。

3.比较质因数

对于每个质因数,防御宝石的乘积中该质因数的出现次数必须大于或等于攻击宝石的乘积中该质因数的出现次数。

4.返回结果

如果所有质因数都满足上述条件,则返回'yes',否则返回'no'

三、完整代码

def solution(n, m, arrayn, arraym):
    from collections import defaultdict
    
    def prime_factors(num):
        factors = defaultdict(int)
        d = 2
        while d * d <= num:
            while (num % d) == 0:
                factors[d] += 1
                num //= d
            d += 1
        if num > 1:
            factors[num] += 1
        return factors
    
    # 统计防御宝石的质因数
    defense_factors = defaultdict(int)
    for num in arrayn:
        factors = prime_factors(num)
        for prime, count in factors.items():
            defense_factors[prime] += count
    
    # 统计攻击宝石的质因数
    attack_factors = defaultdict(int)
    for num in arraym:
        factors = prime_factors(num)
        for prime, count in factors.items():
            attack_factors[prime] += count
    
    # 比较质因数
    for prime, count in attack_factors.items():
        if defense_factors[prime] < count:
            return "no"
    
    return "yes"

if __name__ == "__main__":
    print(solution(2, 5, [10, 12], [2, 3, 5, 2, 1]) == "yes")
    print(solution(4, 5, [7, 2, 5, 3], [2, 4, 5, 6, 1]) == "no")

四、对代码的分析

1.分解质因数

我们可以编写一个函数 prime_factors(num),该函数接受一个整数 num,并返回一个字典,字典的键为质因数,值为该质因数的出现次数。例如prime_factors(12) 返回 {2: 2, 3: 1}

2.统计防御宝石的质因数

遍历防御宝石的数组 arrayn,对每个元素调用 prime_factors 函数,并将结果累加到一个字典 defense_factors 中。defense_factors 字典的键为质因数,值为该质因数的总出现次数。

3.统计攻击宝石的质因数

遍历攻击宝石的数组 arraym,对每个元素调用 prime_factors 函数,并将结果累加到一个字典 attack_factors 中。attack_factors 字典的键为质因数,值为该质因数的总出现次数。

4.比较质因数

遍历 attack_factors 字典,对于每个质因数,检查 defense_factors 中该质因数的出现次数是否大于或等于 attack_factors 中的出现次数。如果存在某个质因数在 defense_factors 中的出现次数小于 attack_factors 中的出现次数,则返回 'no'。如果所有质因数都满足条件,则返回 'yes'

五、复杂度分析

时间复杂度

分解质因数的时间复杂度为 O(n​),其中 n 是待分解的数。对于每个防御宝石和攻击宝石,我们都需要分解其质因数,因此总的时间复杂度为 O(na​+mb​),其中 a 和 b 分别是防御宝石和攻击宝石的最大值。

空间复杂度

我们需要存储每个质因数的出现次数,因此空间复杂度为 O(k),其中 k 是质因数的数量。

六、总结

通过分解质因数的方法,我们可以将乘积的整除问题转化为质因数的比较问题。这种方法不仅简单直观,而且效率较高。通过统计防御宝石和攻击宝石的质因数,并比较它们的质因数出现次数,我们可以有效地判断小U是否能够抵抗住boss的攻击。