📅  最后修改于: 2023-12-03 15:36:26.312000             🧑  作者: Mango
问题描述: 给定一个整数数组 $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$ 所需的最小删除的解决方案。