📌  相关文章
📜  使数组的GCD等于1所需的最小删除(1)

📅  最后修改于: 2023-12-03 15:36:26.312000             🧑  作者: Mango

使数组的GCD等于1所需的最小删除

问题描述: 给定一个整数数组 $A$,我们可以执行一些操作来使 $A$ 中的每个元素都除以一个整数。比如,如果 $A = [1,2,3,4,5,6]$,我们可以将其除以 $2$ 得到 $A = [1,1,3,2,5,3]$。我们想要使得 $A$ 的最大公约数(GCD)等于 $1$。请问,我们需要最少删除多少个元素?

解决思路: 根据题目,我们需要找到一些方法来除掉数组中一些元素,使得最终数组的 GCD 等于 $1$。令 $g = \text{GCD}(A)$,则我们需要找到所有不能被 $g$ 整除的元素,即将它们除掉即可。

如果 $g = 1$,那么 $A$ 中的所有元素都可以不删除,因为它们已经互质。如果 $g > 1$,则我们需要找到不能被 $g$ 整除的元素。这个问题可以通过枚举 $g$ 的因子来处理。对于每个因子 $d$,我们将 $A$ 中的所有能被 $d$ 整除的元素删除,这样就可以保证最后得到的数组的 GCD 为 $1$。

为了方便删除操作,我们可以使用一个 bool 数组 $delete$ 来记录是否要删除对应的元素。我们首先将所有元素标记为不删除,然后对于枚举到的因子 $d$,我们将所有能被 $d$ 整除的元素标记为删除。最后统计未被标记的元素个数即为需要删除的最少元素个数。

时间复杂度: 枚举 $g$ 的因子的时间复杂度为 $O(\sqrt{g})$,对于每个因子我们需要遍历整个数组来标记要删除的元素,总时间复杂度为 $O(n\sqrt{g})$,其中 $n$ 为数组长度。

以下是 Python 代码实现:

def min_removals(A):
    # 计算最大公约数
    g = A[0]
    for i in range(1, len(A)):
        g = math.gcd(g, A[i])
    # 如果最大公约数已经是 1,无需删除
    if g == 1:
        return 0
    # 标记要删除的元素
    n = len(A)
    delete = [False] * n
    for d in range(2, int(math.sqrt(g)) + 1):
        if g % d == 0:
            for i in range(n):
                if A[i] % d == 0:
                    delete[i] = True
    # 统计未被标记的元素个数
    count = 0
    for i in range(n):
        if not delete[i]:
            count += 1
    return n - count

以上就是使数组的 GCD 等于 $1$ 所需的最小删除的解决方案。