所以它工作正常,需要的两个主要更改是只检查 x 的平方根(还需要将我的检查案例从检查余数翻转到检查幂)。另一个变化是使用双倍显然是鲁莽的,因为数字将远远超过最大双倍。
这是来自 CodeEval 的挑战,我想首先是由 Facebook 提出的。这是我的大脑立即吐出来的。它通过了所有手动测试用例(例如 10-> 1、25->2、3-> 0)。我还没有看到任何其他解决方案,因为我想先看看我是如何处理自己的想法的。如果我离基地很远而且这永远不会奏效,我会很感激有人这么说:P。如果这永远行不通,我必须想出一个新的方法,我会花更多的时间来研究这个。
我没有立即看到它不会满足的任何情况..但这不是问题。我从来都不擅长计算运行时复杂度,但我认为我的嵌套太多了。
我想通过左右检查(这在代码中更清楚一点),我会严重减少运行时间。我不确定这是否只是没有像我想象的那样有效,或者其他循环仍然太多......或两者兼而有之。
有什么想法吗?这是可以挽救的还是我应该放弃它并以新的方式思考它?
问题和代码如下。感谢您的关注:-)
致谢:这个挑战出现在 2011 年 Facebook 黑客杯上。
双平方数是一个整数 X,可以表示为两个完全平方之和。例如,10 是一个双平方,因为 10 = 3^2 + 1^2。你在这个问题中的任务是,给定 X,确定它可以写成两个平方和的方式的数量。例如,10 只能写成 3^2 + 1^2(我们不认为 1^2 + 3^2 不同)。另一方面,25 可以写成 5^2 + 0^2 或 4^2 + 3^2。
注意:不要尝试蛮力方法。不起作用。以下约束成立:
0 <= X <= 2147483647
1 <= N <= 100
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class DoubleSquares {
public static void main(String[] args) throws IOException {
File file = new File(args[0]);
BufferedReader in = new BufferedReader(new FileReader(file));
String line;
while ((line = in.readLine()) != null) {
int total = 0;
String[] lineArray = line.split("\\s");
if (lineArray.length > 0) {
double x = (double) Integer.parseInt(lineArray[0]);
if (x == 0){total++;} //special case if input is 0
double sLeft = 0.00; //left boundary to indicate where to stop (so we dont repeat e.g. 4+1 and 1+4)
for(double sRight = x; sRight > sLeft; sRight--){
if (Math.sqrt(sRight) % 1 == 0){//has no remainder then it's a candidate..
double needed = x-sRight;
if (Math.sqrt(needed) % 1 == 0){//check of solution to what makes sRight == x is a perfect square.
total++; //increment if so.
}
sLeft = needed;
}
}
}
System.out.println(total);
}
}
}
更清楚一点,这似乎工作得很好,但是当我提交给 CodeEval 自动评分器时,它会在运行 10 秒后终止。毫无疑问,太慢或卡住了一些大输入。