UVA 10023 SquareRoot问题

时间:2014-07-08 19:25:10

标签: java algorithm

我遇到了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;
    }
} 

可以肯定它不是最好的性能解决方案而且似乎是错误的,但有人可以解释一下它出错的原因吗?

谢谢你们!

1 个答案:

答案 0 :(得分:1)

从问题陈述中:

  

输出

     

对于每个测试用例,程序应以与输入中给出的Y相同的格式打印X.

     

在两个连续测试用例的输出之间打印一个空行。

我通过修改您的计划来接受提交,以便将此考虑在内。

但是,我建议使用二进制搜索作为一种更简单的方法(但是由于没有给出测试用例的数量,我认为这个问题似乎没有得到很好的定义)。