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

66 阅读3分钟

问题分析

题目要求我们判断是否可以通过一系列操作,使得数组中的每个元素最多只包含一种素因子。每次操作可以选取两个元素 𝑎𝑖ai​ 和 𝑎𝑗aj​,然后选择 𝑎𝑖ai​ 的一个因子 𝑥x,将 𝑎𝑖ai​ 变为 𝑎𝑖/𝑥ai​/x,并将 𝑎𝑗aj​ 变为 𝑎𝑗×𝑥aj​×x。

关键点在于:

  • 每次操作不会改变所有元素中素因子的总数。
  • 如果最终每个元素最多只包含一种素因子,那么整个数组中不同素因子的数量不能超过数组长度(因为每个元素只能持有一种素因子)。

解决方案思路

  1. 分解素因子:首先我们需要能够将每个数分解为其素因子。这可以通过试除法来完成,即从2开始尝试除以每个可能的素数直到其平方大于该数为止。
  2. 统计不同的素因子:对于给定数组中的每个数,我们都需要找出它所有的素因子,并记录下来。通过集合或计数器来追踪这些素因子,确保我们可以知道总共有多少种不同的素因子。
  3. 判断可行性:如果不同素因子的数量小于等于数组的长度,则说明有可能通过适当的操作使得每个元素最多只含有一种素因子。否则,不可能达到目标状态。

代码详解

Python
深色版本
from collections import Counter
from math import sqrt

# 辅助函数,用于获取一个整数的所有素因子
def prime_factors(n):
    i = 2
    factors = []
    # 用i去除n,直到i*i大于n
    while i * i <= n:
        if n % i:  # 如果i不是n的因子
            i += 1
        else:
            n //= i  # 将n除以i
            factors.append(i)  # 记录下这个因子
    if n > 1:  # 如果最后n还大于1,说明n本身也是一个素数
        factors.append(n)
    return factors

def solution(n: int, a: list) -> str:
    all_factors = []  # 用于存储数组中所有数的素因子
    for num in a:
        all_factors.extend(prime_factors(num))  # 对数组中的每个数进行素因子分解
    
    factor_count = len(Counter(all_factors))  # 统计不同素因子的数量
    
    # 判断不同素因子数量与数组长度的关系
    if factor_count <= n:  # 如果不同素因子数量不超过数组长度
        return "Yes"
    else:
        return "No"

# 测试样例
if __name__ == '__main__':
    print(solution(4, [1, 2, 3, 4]) == "Yes")  # 应输出True
    print(solution(2, [10, 12]) == "No")       # 应输出True
    print(solution(3, [6, 9, 15]) == "Yes")    # 应输出True

代码解释

  • prime_factors 函数实现了对单个整数的素因子分解。
  • 在 solution 函数里,我们首先初始化一个空列表 all_factors 来存放数组中所有元素的素因子。
  • 遍历数组 a 中的每个元素,调用 prime_factors 并将结果添加到 all_factors 中。
  • 使用 Counter 统计 all_factors 中不同素因子的数量。
  • 根据不同素因子数量与数组长度的关系决定返回 "Yes" 或 "No"。

这种方法有效利用了数学性质,通过简单而直接的方式解决了问题。