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

120 阅读3分钟

问题描述

小M拿到一个数组,她可以进行多次操作,每次操作可以选择两个元素 aia_i 和 aja_j,并选择  aia_i 的一个因子 x,然后将 aia_i 变为 ai/xa_i/x,并将 aja_j 变为 aj×xa_j\times x。她的目标是通过有限次操作,使得数组中的每个元素最多只包含一种素因子。

素因子的定义是:若 x 能被素数 p 整除,那么 p 是 x 的一个素因子。例如,12 的素因子有 2 和 3。

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

测试样例

样例1:

输入:n = 4 ,a = [1, 2, 3, 4]
输出:'Yes'

样例2:

输入:n = 2 ,a = [10, 12]
输出:'No'

样例3:

输入:n = 3 ,a = [6, 9, 15]
输出:'Yes'

算法步骤

假设我们有一个数组 a = [6, 9, 15],数组长度 n=3。

素因子分解

  • 6 的素因子:2, 3
  • 9 的素因子:3, 3
  • 15 的素因子:3, 5

因为题目要求的是每个元素最多包含一个素因子,所以我们可以将一样的素因子都放在一起,拿这个例子来说,我们可以首先操作6和9,将6中的3除掉,9乘3,那么每个元素如下:

  • 6 的素因子:2
  • 9 的素因子:3, 3, 3
  • 15 的素因子:3, 5

同理,将15的3除掉,9乘3:

  • 6 的素因子:2
  • 9 的素因子:3, 3, 3, 3
  • 15 的素因子:5

可以看到此时每个元素都已经只包含一个素因子了

结论

所以我们只需要判断所有数组元素中出现的素因子个数即可,它如果小于等于n,则满足题目要求,至于为什么可以小于n,是因为题目要求最多包含一个素因子,可以没有素因子,我们除的次数多了之后有的元素会变成1,它也是没有素因子的。

关键点

  1. 素因子分解:首先,我们需要对数组中的每个元素进行素因子分解,找出每个元素的所有素因子。
  2. 素因子集合:将所有元素的素因子放入一个集合中,统计每个素因子的出现次数。
  3. 判断条件:如果素因子的种类数不超过数组的长度 n,那么可以通过操作将每个元素的素因子种类减少到一种。否则,无法实现。

代码实现思路

  1. 素因子分解:对数组中的每个元素进行素因子分解,找出每个元素的所有素因子。
  2. 统计素因子:将所有素因子放入一个集合中,统计每个素因子的出现次数。
  3. 判断结果:如果素因子的种类数不超过数组的长度 n,则输出 "Yes",否则输出 "No"
#include <iostream>
#include <vector>
#include <set>

using namespace std;


string solution(int n, vector<int>& a) {
    // write code here
    set<int> se;
   for (auto x : a) {
        for (int i = 2; i <= x / i; i++) {
            if (x % i == 0) {
                while (x % i == 0) {
                    x /= i;
                }
                se.insert(i);
            }
        }
        if (x != 1) se.insert(x);
   }
   if (se.size() <= n) return "Yes";
   return "No";
}

int main() {
    vector<int> a1 = {1, 2, 3, 4};
    vector<int> a2 = {10, 12};
    vector<int> a3 = {6, 9, 15};

    cout << (solution(4, a1) == "Yes") << endl;
    cout << (solution(2, a2) == "No") << endl;
    cout << (solution(3, a3) == "Yes") << endl;
    return 0;
}

image.png