找到与给定数字相加的四个连续数字

时间:2010-07-01 20:19:35

标签: algorithm

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

因此,如果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;
            }
        }
    }
}

9 个答案:

答案 0 :(得分:39)

开始
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:< / p>

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是整数,{{1} }是奇数,所以它的平方根,如果是一个整数,也是奇数,5-4z将是一个整数。)

因此,测试x是否为整数,然后测试z = sqrt(y+1)是否为完美正方形。

答案 1 :(得分:13)

您只需要测试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看起来很小。

答案 2 :(得分:6)

对于很多数字,我们可以很容易地看出它们是否适合某个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.

答案 3 :(得分:5)

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

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

答案 4 :(得分:5)

计算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 :(得分:4)

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

答案 6 :(得分:3)

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

答案 7 :(得分:2)

您的等式可以简化为

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

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

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

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


上限和下限

由于Wolfram Alpha经过一些细致的改进,已经完成了两件事:

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

    所以...

    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精炼为仅整数之后,在所有情况下,只有一个数字可以检查,因为您的范围减少到一个数字。凉! (感谢Brian)

答案 8 :(得分:0)

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

在序列x,x + 1,... x + 3之外,我们知道某些值必须小于z,并且某些值必须大于z(因为它们不能都等于z)

所以,我们知道

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

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