📅  最后修改于: 2023-12-03 14:53:38.557000             🧑  作者: Mango
给定两个长度相同的整型数组 A 和 B,求满足条件 X % A[i] = B[i] 的最小正整数 X(X 一定存在),如果不存在,则返回 -1。
由于 X % A[i] = B[i],那么根据模运算的性质可以得到以下等式:
X = k * A[i] + B[i]
其中 k 为一个非负整数,B[i] 为余数。
对于所有的 i,都必须满足 X % A[i] = B[i],也就是说,对于每个 i,都有:
k * A[i] + B[i] ≡ B[i] (mod A[i])
两边同时减去 B[i],得到:
k * A[i] ≡ 0 (mod A[i])
根据同余定理,k * A[i] ≡ 0 (mod A[i]) 等价于 k ≡ 0 (mod A[i]) 或者 A[i] ≡ 0 (mod A[i])。
如果 A[i] = 0,则 X 可以任取正整数,即 X 的取值范围是从 0 到正整数的最大值 INT_MAX。
如果 A[i] ≠ 0,则 k 最小为 A[i],因为 A[i] 的倍数加上余数 B[i] 最小为 A[i]。
综上,X 的最小值取决于所有 A[i] 的最小公倍数,即 lcm(A[0], A[1], ..., A[n-1]),以及对应的 B[i],因此我们可以首先求出 A 数组中所有数的最小公倍数 lcm_A,然后检查是否存在任何一个 i 使得 lcm_A % A[i] ≠ 0,如果存在,则说明不存在满足条件的 X,返回 -1;否则,按照上述算法计算 X 的最小值,即为 lcm_A + k,其中 k 为满足所有 A[i] | (lcm_A + k) 的最小正整数。
def min_x(A: List[int], B:List[int]) -> int:
from math import gcd
lcm_A = 1
for a in A:
lcm_A = lcm_A * a // gcd(lcm_A, a)
if any(lcm_A % a != 0 for a in A):
return -1
k = 0
for i, a in enumerate(A):
while (lcm_A + k) % a != B[i]:
k += lcm_A
if k > 2 * lcm_A:
return -1
return lcm_A + k
其中 List[int]
表示整型数组类型,使用方法类似于 Python 中的内置列表类型 list
。math.gcd
函数用于求两个数的最大公约数,//
操作符表示整数除法,any
函数用于判断任意一个元素是否为真。