从两个列表中计算对,当它们相乘时形成一个完美的正方形

Posted

技术标签:

【中文标题】从两个列表中计算对,当它们相乘时形成一个完美的正方形【英文标题】:Compute pairs from two lists that when multiplied make a perfect square [duplicate] 【发布时间】:2020-05-30 04:40:47 【问题描述】:

给你两个列表,你必须找出构成完美正方形的对。

例如在:

a = [2, 6, 10, 13, 17, 18]

b = [3, 7, 8, 9, 11, 15]

有两对(2,8)(8,18)

有没有比蛮力更有效的方法? 这是我的代码,时间复杂度为 O(n*m) (其中 n 是 a 的长度,m 是 b 的长度)。

pl = []
a = [ 2, 6, 10, 13, 17,18]
b = [ 3, 7, 8, 9, 11, 15 ]
i = 0
while(i < len(a)):
    j = 0
    while(j < len(b)):
        p = a[i]*b[j]
        n = p**0.5
        u = int(n)
        if n == u:
            pl.append((a[i],b[j]))

        j = j+1


    i = i+1

print(pl)

在使用 C#here 之前已经问过这个问题,但我不明白他们的意思是“我们需要为每个数字存储的是它的哪个素数具有奇数”,所以我可以不要在我的 Python 代码中实现它。

有人可以向我解释一下我们如何在 Python 中实现一个高效的解决方案吗?

【问题讨论】:

【参考方案1】:

链接问题中描述的逻辑如下。完美正方形的质因数总是成对出现。例如,36 = 2*2*3*3。我们有两个3s 和两个2s。因此,如果我们将任意两个数相乘形成一个完美的平方,如果我们将它们的每个素数相加,我们也会得到偶数。

例如,8 = 2*2*218 = 2*3*3。结合起来,我们得到四个2s 和两个3s。

以下是一些实现此算法的 Python 代码,使用 collections.Counter 并设置删除重复项。首先,我们预先计算ab 中每个唯一元素的所有素数分解以避免冗余,并将其存储在字典中。然后,我们使用itertools.product 循环遍历来自ab 的元素对,并结合主要因子计数。如果每个计数都是偶数,我们将排序后的对添加到集合中。

代码:

from collections import Counter
import itertools

def prime_factors(n):
    """
    https://***.com/a/22808285/12366110
    """
    i = 2
    factors = []
    while i * i <= n:
        if n % i:
            i += 1
        else:
            n //= i
            factors.append(i)
    if n > 1:
        factors.append(n)
    return Counter(factors)

a = [2, 6, 10, 13, 17,18]

b = [3, 7, 8, 9, 11, 15]

prime_factors = i: prime_factors(i) for i in set(a) | set(b)

rv = set()

for a, b in itertools.product(a, b):
    combined_counts = prime_factors[a] + prime_factors[b]
    if all(v%2 == 0 for v in combined_counts.values()):
        rv.add(tuple(sorted([a, b])))

输出:

>>> rv
(2, 8), (8, 18)

【讨论】:

itertools.product(a, b) 不让它按 m * n 排序吗?

以上是关于从两个列表中计算对,当它们相乘时形成一个完美的正方形的主要内容,如果未能解决你的问题,请参考以下文章

当 Python 中的输入是大数时,如何有效地在一个范围内找到完美的正方形

线性代数的本质-07-点积与对偶性

CSS - 具有完美正方形的网格[重复]

包括两个端值的完美正方形

完美正方形-深度遍历

C语言怎么求正方形面积和圆的周长和面积