有没有办法将任何数字表示为4个方格的总和。
例如,29可以表示为5 ^ 2 + 2 ^ 2 + 0 ^ 2 + 0 ^ 2
我尝试了以下代码,但是一些数字给出了15个例子,例如23 ^ 4 + 2 ^ 2 + 1 ^ 2 + 1 ^ 2 + 1 ^ 2
我尝试的代码是:
x=0;
while(num!=0){
x=(int)Math.floor(Math.sqrt(num));
num=num-(x*x);
}
答案 0 :(得分:8)
与波希米亚人所说的不同,我用以下四个方面解决了23个问题:
23 = 3^2 + 3^2 + 2^2 + 1^2
29如下:
29 = 4^2 + 3^2 + 2^2 + 0^2
我的逻辑将从:
开始SQRT(29) = 5 - 1 = 4;
这是我们的第一个任期。注意:这是针对您的简单案例。对于复杂的情况,例如323,这可能不起作用。
323 = 17^2 + 4^2 + 3^2 + 3^2
请记住,当您找到x项时,该项的值小于或等于 x-1(上一个)项的值。
答案 1 :(得分:3)
以下是您的算法代码
这将为您提供所有可能的组合......
int n, t1, t2, t;
n = 29;//Your number
for (int i = (int) Math.sqrt(n / 4); i * i <= n; i++) {
t1 = n - i * i;
for (int j = (int) Math.sqrt(t1 / 3); j <= i && j * j <= t1; j++) {
t2 = t1 - j * j;
for (int k = (int) Math.sqrt(t2 / 2); k <= j && k * k <= t2; k++) {
t = (int) Math.sqrt(t2 - k * k);
if (t <= k && t * t == t2 - k * k) {
System.out.println("(" + i + "^2) + (" + j + "^2) + ("+ k + "^2) + ("+ t +"^2)");
}
}
}
}
答案 2 :(得分:3)
在最初回答错误之后,我想我会对其进行编码:此解决方案有效。
我已经测试了这段代码并且它在O(log n)时间内执行,直到非常大的数字(在旧的macbook pro上解决n = Long.MAX_VALUE在75 ms内)
public static void main(String[] args) {
long number = 827347833323423451L;
LinkedList<Long> solution = new LinkedList<Long>();
if (fourSquares(number, solution))
System.out.println(number + " = sum of squares of: " + solution);
else
System.out.println(number + " could not be solved"); // never happens
}
public static boolean fourSquares(long number, LinkedList<Long> solution) {
if (number == 0) {
for (long i = solution.size(); i < 4; i++)
solution.add(0L);
return true;
}
if (solution.size() == 4)
return false;
for (long i = (long) Math.sqrt(number); i > 0; i--) {
solution.add(i);
if (fourSquares(number - i * i, solution))
return true;
solution.removeLast();
}
return false;
}
输出:
9223372036854775807 = sum of squares of: [3037000499, 76994, 671, 23]
答案 3 :(得分:2)
所以,我无法理解这一点,并使用动态编程,特别是memoization在Java中解决它。
以下是相关位:
private final Map<Integer, int[]> memo = new HashMap<Integer, int[]>();
/**
* @param n
* the number
* @return int[]
*/
public int[] solveFor(final int n) {
if (memo.containsKey(n)) {
return memo.get(n);
}
final int[] a = new int[4];
a[0] = (int) Math.floor(Math.sqrt(n));
if (sumOfSquares(a) < n) {
int[] b = solveFor(n - a[0] * a[0]);
while (a[0] > 0 && b[3] > 0) {
// won't fit
a[0]--;
b = solveFor(n - a[0] * a[0]);
}
System.arraycopy(b, 0, a, 1, 3);
}
memo.put(n, a);
return a;
}
在这个低至2.4GHz的i5上,它可以在不到3秒的时间内计算出从0到2,000,000的所有分解。
当然,明显的缺点是,如果要求计算所有整数到大数字,它会很快耗尽内存。但是,如果它被要求解决,比如4200万,那么它可以在几毫秒内生成正确的答案。
我也很确定它仍然可以被改进/优化 - 特别是如果它发现剩余的解决方案太长而无法适应剩余的空间,那么只是递减第一项的部分,但我会将其保留为为有更好的数学技能和更多空闲时间的人练习。 :)
答案 4 :(得分:1)
这很难实现,因为如果一个素数介于两者之间,你永远不能将它打破为1的平方根;例如,
拿11,
3 ^ 2 ---现在2仍然是没有平方根,小于此数字是“1”,1 ^(n)总是1 ..所以总是有一个提醒..
所以可能你需要遵循某种算法,因为其他答案建议......
答案 5 :(得分:-1)
代码没有问题。
23只需要5个术语来解决。
如果达到限制4,请尝试计算术语数并终止循环。
查看我的其他(更好)答案