假设有一个给定的数字我们应该测试它是否是四个连续数字的乘积?
因此,如果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;
}
}
}
}
答案 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必须至少能被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
的第四个根,将其向下舍入并将其称为a
。 a(a-1)(a-2)(a-3)
远小于y
。计算y
的第四个根,将其四舍五入,并将其称为b
。 b(b+1)(b+2)(b+3)
远远超过y
。现在,您有三个可能的数字:a-2
,a-1
和a
(注意a = b
或a = 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经过一些细致的改进,已经完成了两件事:
所以...
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。