【问题标题】:number of ways in which N can be represented as product of K factors in jsjs中N可以表示为K因子乘积的方式数
【发布时间】:2018-12-30 06:28:30
【问题描述】:

给一个数字 N,一个包含所有因子的数组,一个数字 K...我们需要找到可以将 N 表示为 K 个因子的乘积的多种方式,即 如果

N=64
K=3
arr = [1,2,4,8,16,32,64]

所以方式数将是 7,因为

1x1x64=64
1x2x32=64
1x4x16=64
1x8x8=64

等等

【问题讨论】:

  • 最近几天有很多类似的问题。同一位讲师或在线比赛?
  • 既然给定了 N,那么它的因子数组是多余的;你可以推断出来。第二个方面 - 标签 node.js 真的无关紧要 - javascript足以指定实现语言

标签: javascript arrays node.js algorithm sorting


【解决方案1】:

要从数组中获取长度为k 的组合,我们可以使用递归生成器:

function* combinations(array, k, i = 0, prepend = []) {
  if(!k) {
    yield prepend;
  } else {
    while(i < array.length)
      yield* combinations(array, k - 1, i /*+ 1*/, prepend.concat(array[i++]));
 }
}

(注释掉的 +1 是为了排除重复项 (1 * 1 * 1),但 OP 似乎不需要这种行为)

所以要得到我们可以做的所有组合:

[...combinations([1, 2, 3, 4], 2)] // [1, 2], [1, 3] ...

现在我们只需要将它们相乘:

const multiply = array => array.reduce((a, b) => a * b);

并过滤掉那些是N的:

[...combinations(arr, K)].filter(el => multiply(el) === N).length

这将返回7

PS:是的,有更简单快捷的方法,但我有时只想使用一些罕见(但很酷)的语言功能:)

【讨论】:

    【解决方案2】:

    这将创建一个包含所有非重复组合的二维数组。

      var n = 64
      var factors = [1, 2, 4, 8, 16, 32, 64]
      var rep = []
    
      for (var f1 = 0; f1 < factors.length; f1++) {
        for (var f2 = 0; f2 < factors.length; f2++) {
          for (var f3 = 0; f3 < factors.length; f3++) {
            if (factors[f1]*factors[f2]*factors[f3] == n && factors[f3] >= factors[f2] && factors[f2] >= factors[f1]) {
              rep.push([factors[f1], factors[f2], factors[f3]])
            }
          }
        }
      }
    
      console.log(rep.length) // Get the amount of combinations
    

    【讨论】:

      【解决方案3】:

      让我们看一下 N 作为素因数的分解。看起来像:

      其中 a1, a2, .. ax 是 N 的质因数。我们可以将这个公式进一步展开为:

      为了产生问题所需的 K 因子,我们必须从上面列出的素数中挑选。任何素数都可以按任意顺序挑选,所以基本上在这个公式中我可以替换素数带有抽象符号的数字。

      有多少种方法可以将 N 拆分为 K 个数字的乘积?将这些下划线分为 K 组的方法有很多——每个 K 数字一组。对于第一个下划线,有 K 种可能将其分配给一个组;同样,每个下划线都有 K 个可能性。总的来说,可能性的数量是

      [这基本上是一个划分问题:我们将 b1+b2+..+bx 项拆分为 K 个集合]

      现在剩下的唯一问题是确定将 N 分解为素因数。或者,更好的是,直接确定总和 b1+b2+...+bx。

      counter=0;
      for(int i=2;i<square_root(N);i++)
          if(N%i==0) //i is a divisor of N
             {
                 int M=N;
                 while(M%i==0)
                     {
                         counter++;
                         M=M/i;
                     }
             }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-21
        • 2023-03-17
        • 2016-01-01
        • 1970-01-01
        • 2022-01-17
        相关资源
        最近更新 更多