不同整数的平方和

时间:2018-11-18 22:38:53

标签: algorithm

您能否提出解决以下问题的任何算法思路:

  

给出正整数 S K N 。查找不同的正整数 x 1 x 2 ,..., x K 这样

     

x 1 2 + x 2 2 + ... + x K 2 = S

     

x i N x 对于所有 i = 1的i < x i +1 K

到目前为止,我知道我应该开始在 S 的平方根下方搜索最大的 x

2 个答案:

答案 0 :(得分:1)

这里是稍微优化的蛮力。正如我在评论中(和近距离投票)所链接的那样,在我看来,我们可以修改标准子集和问题以使用正方形。

JavaScript代码(输出末尾的省略号表示将其余的数字加到1):

function f(S, K, N){
  function g(s, k, n, c){
    const minS = k*(k+1)*(2*k+1)/6;
    const maxN = Math.min(
      n,
      ~~Math.sqrt(s - (k-1)*k*(2*k-1)/6)
    );

    if (s < minS || maxN < 1)
      return [];
    else if (s == minS)
      return [c.concat([k, '...'])];
    if (k == 0)
      return [];
    
    return g(s - maxN*maxN, k - 1, maxN - 1, c.slice().concat(maxN))
      .concat(
        g(s, k, maxN - 1, c)
      );
  }
  
  return g(S, K, N, []);
}

for (let j=1; j<6; j++)
  console.log(JSON.stringify([178, j, f(178, j, 100)]));

console.log(JSON.stringify([178, 5, f(178, 5, 10)]));

答案 1 :(得分:1)

由于您要的是算法主意,而不是确切的答案,所以这是我的2美分。

您可以通过查找从1, 4, 9, 16, 25...1的所有理想平方(例如S)并将其放入{{1} }。

然后,如果您可以解决以下(更一般的)问题,则可以轻松解决原始问题。

一般问题:

给定一个任意集PerfectSquareSetLessThanS,找到V的一个子集W,其子集正好具有V个数字,使得它们的总和为K

虽然我还没有一个精确的解决方案,但是您的一般问题看起来很像一个众所周知的问题,称为3SUM问题。

3SUM问题询问是否给定一组S数字,是否存在3个数字之和,它们的总和为0。Wikipedia页面概述了一种搜索这种连音的算法。

请注意,3SUM问题具有不同的变式,其中一个是k-SUM(在上段中用k替换3),另一个是非零和变式。也许您可以找到这两种变体的组合来构建通用解决方案。