我遇到了this UVA的问题,因为我无法弄清楚为什么我的解决方案不好。
只要我理解,问题是获得从1到10 ^ 1000的任何给定数字的整数平方根。所以我的目的是从位置i / 2翻转BigInteger的位,其中i是输入的最小二进制补码表示中的位数,并且每当我的猜测平方仍然小于时,减小i值。输入。
请注意,到目前为止我尝试的每个输入都获得了预期的结果!
例如,sqrt(36)的例子是:
36 -> 100100
bitCount = 2 ( (6 - 1)/2 = 2)
guess = 100 (4)
(4 * 4 = 16 < 36) -> bitCount = 1;
guess = 110 (6)
(6 * 6 = 36 = 36) -> break;
所以sqrt(36)的解决方案是6,真棒......这样对sqrt(37),sqrt(38),sqrt(39)的解决方案,直到sqrt(49)也是6。
也许代码更具说明性。
import java.math.BigInteger;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
BigInteger bi;
for(int i = n; i != 0; i--){
bi = new BigInteger(in.next());
System.out.println(squareRoot(bi));
}
in.close();
}
private static BigInteger squareRoot(BigInteger N) {
int bitCount = (N.bitLength() - 1)/2;
int aux = 0;
BigInteger guess = BigInteger.ZERO;
while(bitCount >= 0){
guess = guess.flipBit(bitCount);
aux = guess.multiply(guess).compareTo(N);
if(aux < 0)
bitCount--;
else if(aux != 0){
guess = guess.flipBit(bitCount);
bitCount--;
}
else{
break;
}
}
return guess;
}
}
可以肯定它不是最好的性能解决方案而且似乎是错误的,但有人可以解释一下它出错的原因吗?
谢谢你们!
答案 0 :(得分:1)
从问题陈述中:
输出
对于每个测试用例,程序应以与输入中给出的Y相同的格式打印X.
在两个连续测试用例的输出之间打印一个空行。
我通过修改您的计划来接受提交,以便将此考虑在内。
但是,我建议使用二进制搜索作为一种更简单的方法(但是由于没有给出测试用例的数量,我认为这个问题似乎没有得到很好的定义)。