題目:UVA 10023 - Square root(手算平方根)
題目大意:求給定的一個數的平方根。
解題思路:用二分但是這個數太大了,就超時了。看題接後發現需要用一種手算平方根的算法。
算法:
先判斷這個數是不是偶數位,是的話就第一次取前面的兩位數,不是的話第一次就只取前面的一位數來作爲被除數。接下來就是兩位兩位爲一節來計算。
用前一次的計算結果乘上20+一個個位數a再乘上這個a,找到最大的a使得這個式子的結果不大於被除數。
被除數減去這個結果然後再在尾巴接上那個大數的接下來兩位作爲新的被除數。
除數就是在原本除數的尾巴接上這個a作爲新的除數。
重複上面的步驟,直到計算完這個大數的最後兩位。最後的除數就是開方數。
代碼:
import java.util.*;
import java.math.*;
import java.io.*;
public class Main {
public static BigInteger sqrt(BigInteger ans) {
BigInteger num = BigInteger.ZERO;
BigInteger res = BigInteger.ZERO;
BigInteger div;
String str = "0" + ans.toString();
int len = str.length();
int i = len % 2;
for (; i < len; i += 2) {
num = num.multiply(BigInteger.valueOf(100)).add(new BigInteger(str.substring(i, i + 2)));
div = res.multiply(BigInteger.valueOf(20));
for (int j = 0; j < 10; j++) {
if (div.add(BigInteger.valueOf(j + 1)).multiply(BigInteger.valueOf(j + 1)).compareTo(num) > 0) {
num = num.subtract(div.add(BigInteger.valueOf(j)).multiply(BigInteger.valueOf(j)));
res = res.multiply(BigInteger.valueOf(10)).add(BigInteger.valueOf(j));
break;
}
}
}
return res;
}
public static void main(String args[]) {
Scanner cin = new Scanner(System.in);
int T = cin.nextInt();
while (T > 0) {
BigInteger n = cin.nextBigInteger();
System.out.println(sqrt(n));
T--;
if (T > 0)
System.out.println();
}
}
}