Algorithm 给定一个数字N和一个数组a。检查N是否可以表示为一个或多个数组元素的乘积

Algorithm 给定一个数字N和一个数组a。检查N是否可以表示为一个或多个数组元素的乘积,algorithm,math,Algorithm,Math,给定一个数字N(其中N,因为您没有显示代码或算法,所以我只给出一个想法。如果您需要更多帮助,请显示您自己在该问题上的更多工作 请注意,N最多可以60位长。这足够小,以至于N可以非常快地分解为它的素因子。因此,首先为这种大小的数字制定一个好的因子分解算法 您的算法将因子N和数组中的每个元素A。如果N中有任何素因子没有分解成A的任何元素,那么您的答案是否。在N=15的示例中就是这种情况 现在,您可以在N和A的元素中使用素因子及其指数。现在,您需要找到一个子集(或者更准确地说,一个子集)在A中,每个素

给定一个数字
N(其中N,因为您没有显示代码或算法,所以我只给出一个想法。如果您需要更多帮助,请显示您自己在该问题上的更多工作

请注意,
N
最多可以
60
位长。这足够小,以至于
N
可以非常快地分解为它的素因子。因此,首先为这种大小的数字制定一个好的因子分解算法

您的算法将因子
N
和数组中的每个元素
A
。如果
N
中有任何素因子没有分解成
A
的任何元素,那么您的答案是
。在
N=15
的示例中就是这种情况

现在,您可以在
N
A
的元素中使用素因子及其指数。现在,您需要找到一个子集(或者更准确地说,一个子集)在
A
中,每个素数的指数加起来等于
N
中的指数。这大大减少了数字的大小,从而使问题更容易解决

最后一部分并非无关紧要。请对此问题进行更多研究,并向我们展示您的一些工作,然后我们可以继续帮助您。

简单伪代码:

A_divisors = set()
for x in A:
    if num % x == 0:
        A_divisors.add(x)

candidates = A_divisors.clone()
seen = set()

while(candidates.size()):
    size = divisors.size()
    new_candidates = set()
    for y in candidates:
        for x in A_divisors:
            if num % (x * y) == 0 and (x * y) not in seen:
                new_candidates.add(x * y)
                seen.add(x * y)
            if x * y == num:
                return true
    candidates = new_candidates

return false

复杂性:O(| A |*k*log k),k是除数的数量。log k是添加和检查元素是否存在于集合中的成本。使用基于哈希的方法,它将是O(1)并且可以删除。我还假设%,*操作为O(1)。

您可以遵循以下方法:

  • 表格2队列:
    Q2
    Q3
  • Q2
    中添加2个,在
    Q3
    中添加3个
  • 获取两个队列头的最小值,例如
    h
    。从相应队列中删除
    h
    。检查它是否等于编号
    N
    。如果是,则返回true。如果大于
    N
    ,则返回false
  • 如果小于
    N
    ,则在
    Q2
    中添加
    2*h
    ,在
    Q3
    中添加
    3*h
    。重复步骤3至4
  • 请注意,当最小
    h
    来自
    Q3
    时,您不需要将
    2*h
    添加到
    Q2
    中。这是因为您之前已经在
    Q3
    中添加了该元素。(我将留给您进行推断。)继续执行此过程,直到
    h
    大于
    N

    如果你有更多这样的数字,你也可以在那里排队。我认为如果你有更多的数字要处理,这是一个最佳的解决方案


    你能猜出这个时间和空间的复杂性吗?< /p>从A的每个元素除以a开始。如果A的元素不平均地分成n,则可以丢弃该元素。考虑<代码> n=15 < /C>和<代码> a={ 2, 3 } /COD>。因为2不均匀地划分为15,它可以被丢弃。如果n=12,A={ 2, 6 },USSR338 6109。。在这种情况下,您的方法显示了错误的答案。@YaseenMollik您的评论毫无意义。所有不是

    N
    除数的数字都可以从
    A
    中删除,而不会影响答案。
    N=12
    A={2,6}
    并不是一个相对明显的反例。在这种情况下,从
    a
    中不删除任何内容最好将其视为预处理步骤。在执行任何其他操作之前,请将
    a
    精简为一个您可以实际使用的集合。有一个经典的算法解决方案。您可以为每个元素创建队列在数组中不断填充,直到找到元素为止。搜索此问题的解决方案,方法也应与您的问题相同:
    找到给定数字的第k个倍数。例如,如果数字是2,3,4,5,则找到可被所有2,3,4,5整除的第6个数字。如果您无法解决此问题,请告诉我。好的回答er(+1)--但你找的不是
    a
    的子集,而是一个子集。一个稍微不同的观点:给定
    N
    的因式分解和
    a
    的元素,用指数向量替换每个数字(包括零作为缺少素数因子的位置标记)。然后问题是将目标向量表示为其他向量的线性组合,使用非负整数作为系数。@JohnColeman:关于多重集,你是对的——我应该使用这个术语。我会尝试尽快将其更改为更清晰的术语。我确实考虑过向量,但我以后会保留它,在提问者展示了更多自己的作品之后。我仍在努力为需要提问者展示更多作品的问题保持良好的平衡,但我认为将向量留待以后是一个不错的选择。很难在给出有用的提示和为他人做家庭作业之间取得平衡,尤其是在这样的情况下这个问题很有意思。评论不是为了进一步的讨论,这次对话已经结束了。