【问题标题】:Find four consecutive numbers that sum to given number找到四个连续数字总和为给定数字
【发布时间】:2016-04-27 21:08:07
【问题描述】:

假设有一个给定的数字,我们应该测试它是否是四个连续数字的乘积?

所以如果y 是我们给定的数字,我们应该测试y = x(x+1)(x+2)(x+3) 是否为任意x

如何为这个问题设计算法?

我是这样做的:

import java.util.*;

public class Product 
{
    public static int product(int i)
    {
         return i * (i+1) * (i+2) * (i+3);
    }

    public static void main(String[] args) 
    {
        Scanner scnr = new Scanner(System.in);
        int x = scnr.nextInt();
        for (int i = 0; i < x/2; i++)
        {
            if (product(i) == x)
            {
                System.out.println("number is product of 4 consecutive numbers");
                break;
            }
        }
    }
}

【问题讨论】:

  • 解决x? SO 系列网站中有没有 dividebyzero.com?
  • @Paul R - 很明显只允许整数解;除非您在谈论整数,否则“连续”一词并不完全适用。
  • @bta:这将很快在 mathoverflow.net 上关闭——对于专业数学家的听众来说太初级了。
  • 初级,亲爱的 Watson,用于 mathoverflow.net,而不是 stackoverflow.com :)

标签: algorithm


【解决方案1】:

开始

y = x(x+1)(x+2)(x+3) = x^4 + 6x^3 + 11x^2 + 6x

请注意,系数看起来几乎是对称的,但最后没有 1。

所以假设

y = z^2 - 1

z^2 = x^4 + 6x^3 + 11x^2 + 6x + 1 

x的所有幂的系数一直到4,x^4和x^0的系数都是1,所以我们需要求x^1的系数,我们称之为a

z = (x^2 + ax + 1)^2 = x^4 + 2ax^3 + (2+a^2)x^2 + 2ax + 1

比较 x^1、x^2 或 x^3 的系数得到a = 3

(上面的方程不要求 x,y 或 z 中的任何一个是整数,但可能会丢失我们不感兴趣的复数或负根)

所以我们可以求解x 的二次方程:

x^2 + 3x + 1 - sqrt(y+1) = 0

给予

x = -3 +/- sqrt(9 - 4 * (1-sqrt(y+1))) 
    ---------------------------------
                2

  = -3 +/- sqrt(5 + 4 sqrt(y+1)) 
    ----------------------------
                2

如果sqrt(y+1) 是一个完美平方z,并且(5+4z) 也是一个完美平方,那么它将是一个整数(如果z 是一个整数,5-4z 是奇数,所以它的平方根,如果一个整数,也是奇数,x 将是一个整数)。

所以先测试z = sqrt(y+1)是否为整数,再测试5+4z是否为完美正方形。

【讨论】:

  • ...因为这是最好的解决方案
  • +1,但需要一段时间才能弄清楚你为什么要这么做。在每一步考虑一个句子来解释。
【解决方案2】:

您只需要测试floor(y**(0.25)-1)。随着 y 接近无穷大,x 接近 y**0.25-1.5(从下方)。

在某种程度上,这是相当直观的。 x*(x+1)*(x+2)*(x+3) 是四个数字的乘积,其平均值等于 x+1.5。当 x 很高时,1.5 看起来很小。

【讨论】:

  • as (x+1)**4 =1, x==floor(y**(0.25)-1) 如下
【解决方案3】:

对于很多数字,我们可以轻松查看它们是否适合某个 X:

  • Y 必须能被 3 整除,因为至少有一个连续数字必须能被 3 整除
  • Y 必须能被 4 整除,因为至少有一个连续数字必须能被 4 整除

所以 Y 必须至少能被 12 (3*4) 整除。 这意味着您可以轻松丢弃大约 92% 的数字。

由于 Y 的值至少包含 X 的 4 次方,因此您可以先取 Y 的 4 次方根(或英文怎么称呼),然后将其四舍五入为整数值,称它为 X 并计算 X(X+1)(X+2)(X+3) 的结果。

结果可能会更高(因为我们忽略了其他因素,例如 X 的 3 次方、X 的 2 次方……)。

现在从 X 中减去 1 并执行相同的计算。

只要结果高于 Y,重复此操作,直到结果低于 Y,或者你正好得到 Y。

【讨论】:

  • Y 是两个偶数的乘积,其中一个是 4 的倍数,因此 Y 是 8 的倍数,因此是 24。
  • 好点,现在你甚至可以扔掉大约 95% 的数字。
  • 很好的答案,你是对的 (x)^(1/4) 被称为“x 的第四根”(或“x 的第四根”)。另外,四个后面不需要连字符,否则你的英语很好!
  • 一般来说,n个连续整数的乘积能被n整除!
【解决方案4】:

计算y 的第四个根,向下取整并命名为aa(a-1)(a-2)(a-3) 远小于 y。数一下y 的第四个根,四舍五入,命名为bb(b+1)(b+2)(b+3) 远远超过 y。现在您可以从三个可能的数字开始:a-2a-1a(注意 a = ba = b-1)。所以检查(a-2)(a-1)a(a+1)(a-1)a(a+1)(a+2)a(a+1)(a+2)(a+3) 就足够了。

【讨论】:

    【解决方案5】:

    编辑:错误地阅读了问题,但它的价值(测试它是否不是四个连续整数的乘积的快速方法):

    任何四个连续整数的乘积都是equal to one less,而不是perfect square

    【讨论】:

    • 反之亦然吗?我认为这就是他所需要的。如果我有 99(比完美平方小一)是 4 个连续整数的乘积吗?
    • 不,不是。 1*2*3*4 = 24, 2*3*4*5 = 120. 99 介于两者之间
    • 嗯,在前几个正方形 1、4、9、16 中,值 3、8 和 15 不起作用,但 y=24 = 1*2*3*4 起作用.
    • 这是测试它是否不是四个连续整数的乘积的好方法,但可能不是测试它是否的好方法>.
    • +1 这很有价值,就好像你假设它是真的一样,你可以将它简化为 y+1 的平方根的二次方,从而得到 Tomex 和我给出的简单结果。所以这个答案很有用。
    【解决方案6】:

    我首先要获取 'y' 的第四根。这将为您提供可以使用的最小 y 因子(即“x”)的近似值。将此作为标准分解算法的基础。

    【讨论】:

      【解决方案7】:

      答案很简单。
      对于给定的数字 y,如果 y+1 不是完全平方,则 y 不是四个连续数字的乘积。 如果 y+1 是完全平方,那么 y 是四个连续数的乘积当且仅当 sqrt(5+4*sqrt(y+1)) 是整数。

      【讨论】:

      • 有趣并且在一些快速测试中似乎是正确的,您能否详细说明一下这背后的理论?
      • 见 Pete Kirkham 的帖子,他写的有点多,但结论完全一样。
      【解决方案8】:

      你的方程可以简化为

      y = x^4 + 6*x^3 + 11*x^2 + 6x
      

      你可以从 x=1 开始向上检查。我们可以注意到一个非常容易计算的上界:y 的 4 次根(或 y 的平方根的平方根)。意思是,当你达到那个数字时,你可以停下来。这对你来说是幸运的,因为对我们来说幸运的是,第四根非常非常非常非常小

      对于高达 10,000 的数字,这很容易检查,因为您最多要检查十个整数。如果您的号码在 500 以下,您最多只需要检查四个整数。

      在 1,000,000+ 时,您将不得不开始检查 31 个或更多的数字,因此它可能开始变得不那么琐碎了。


      上限和下限

      由于Wolfram Alpha的缘故,经过一番细心的细化,总结出两点:

      1. 更精确的 y^0.25 - 1.2 上限
      2. y^0.25 - 1.5 的明确下限

      所以...

      y = num_to_check
      k = Math.sqrt(Math.sqrt(y))   # or Math.pow(y,0.25)
      lower = int(k-1.5)
      upper = int(Math.ceil(k-1.2))
      for n in (lower...upper)
        if n * (n+1) * (n+2) * (n+3) == y
          return n
        end
      end
      return nil
      

      请注意,在这种情况下,对于任何给定的y,最多需要检查两个 数字。

      编辑:在将 x 精炼为仅整数之后,在所有情况下,似乎只有一个数字需要检查,因为您的范围减少到一个数字。凉爽的! (感谢布赖恩)

      【讨论】:

      • 或者他可以在1 .. k中进行二分搜索。
      • @IVlad : int(k-1.5)-int(k-1.2)
      • (10*11*12*13)**0.25 = 11.44...。整数(11.44 - 1.5)!= 整数(11.44 - 1.2)。当然,您实际上只需要测试一个值,因为您的数字必须高于下限且低于上限,而int 将它们都向下舍入而不是其中一个向上舍入。
      【解决方案9】:

      正如其他人所说,从 y 的第 4 个根开始(我们称之为 z)。

      在序列x, x+1,...x+3中,我们知道有些值必须小于z,有些值必须大于z(因为它们不可能都等于z) .

      所以,我们知道

      x <= ceiling(z)
      x+3 >= floor(z)
      

      这为您提供了一个非常小的数字范围来尝试 x。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-27
        • 1970-01-01
        • 2021-08-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多