小M的数组变换 | 豆包MarsCode AI刷题

315 阅读3分钟

小M的数组变换

题目表述

小M得到了一个数组,并且她可以进行多次操作。每次操作中,她可以选择两个元素 ( a_i ) 和 ( a_j ),并选择 ( a_i ) 的一个因子 ( x ),将 ( a_i ) 变为 ( \frac{a_i}{x} ),并将 ( a_j ) 变为 ( a_j \times x )。小M的目标是通过有限次操作,使得数组中的每个元素最多只包含一种素因子。

任务是判断是否有可能通过有限次操作,使数组中的每个元素最多只包含一种素因子。如果可以,输出 "Yes",否则输出 "No"。

思路分析

要解决这个问题,首先需要理解素因子的概念。素因子是一个数的所有质数因子,例如,12 的素因子为 2 和 3。我们的目标是通过操作,使得数组中的每个元素都只包含一种素因子。

  1. 素因子的提取:对于数组中的每个元素,我们需要提取出其所有的素因子。
  2. 素因子的统计:将所有元素的素因子汇总,统计不同的素因子数量。
  3. 判断条件:如果不同素因子的数量不超过数组的长度 ( n ),则可以通过操作将每个元素变为只包含一种素因子的形式,返回 "Yes";否则返回 "No"。

代码详解

下面是实现上述思路的 Python 代码:

from math import gcd
from functools import reduce

def solution(n: int, a: list) -> str:
    # 辅助函数:分解素因子
    def prime_factors(num):
        factors = set()
        d = 2
        while num > 1:
            while num % d == 0:
                factors.add(d)
                num //= d
            d += 1
            if d * d > num:
                if num > 1:
                    factors.add(num)
                break
        return factors

    # 获取所有数的所有素因子
    all_factors = set()
    for num in a:
        all_factors.update(prime_factors(num))
    
    # 如果素因子的数量不超过数组长度,那么可以实现目标
    if len(all_factors) <= n:
        return "Yes"
    else:
        return "No"

if __name__ == '__main__':
    print(solution(4, [1, 2, 3, 4]) == "Yes")
    print(solution(2, [10, 12]) == "No")
    print(solution(3, [6, 9, 15]) == "Yes")

代码解释

  1. prime_factors(num) 函数用于提取一个数的所有素因子,使用了试除法。
  2. solution 函数中,我们遍历数组 a,对每个元素调用 prime_factors 函数,并将所有不同的素因子存储在集合 all_factors 中。
  3. 最后,通过比较 all_factors 的长度与 ( n ) 的大小,决定输出 "Yes" 或 "No"。

个人思考与分析

在这个问题中,关键是理解素因子的概念以及如何有效地提取素因子。通过集合来存储素因子,避免了重复计数,使得判断条件的实现变得简单而高效。此外,使用试除法提取素因子是一种直接且易于理解的方法,但在处理非常大的数时,可能会有性能问题。

错题分析

在解决这个问题的过程中,可能会遇到一些样例不通过的情况。例如,考虑输入 n = 2a = [10, 12],预期输出为 "No",因为 10 的素因子为 2 和 5,而 12 的素因子为 2 和 3,二者有公共素因子 2,但它们的素因子数量超过了数组长度。

在处理这类问题时,重要的是要仔细分析每个元素的素因子,确保没有遗漏。在我的初始解答中,可能没有充分考虑到所有元素之间的素因子关系,导致错误的判断。因此,确保素因子的统计和比较是准确的,是解决此类问题的关键。