JAVA BigInteger 类用例 1:求一个大整数的平方根的整数部分 (SGU 111)


111. Very simple problem

Time Limit: 0.25 sec, Memory Limit: 1 MB

You are given natural number X. Find such maximum integer number that it square
is not greater than X.

Input

Input file contains number X (1 ≤ X ≤ 10^1000).

Output

Write answer in output file.

Sample Input

16

Sample Output

4

题意很简单,就是求一个可能多达1000位的正整数 X 的平方根的整数部分。

初学 JAVA ,用 JAVA 的 BigInteger 类来实现牛顿迭代求平方根 (很多库函数不知道,靠自己来写咯)。

import  java.math. * ;
import  java.io. * ;

public   class  Solution  {
    
// 将字符串转为正整数
    static int str2int (String str)    // 0 <= the integer <= 2 ^ 31 -1
    {
        
int ret = 0;
        
for (int i = 0, j = str.length (); i < j; i ++)
        
{
            ret 
= ret * 10 + str.charAt(i) - '0';
        }

        
return ret;
    }

    
// 将正整数转为字符串
    static String int2str (int i)    // 0 <= i <= 2 ^ 31 -1
    {
        StringBuffer sb 
= new StringBuffer ("0000000000");
        
int digit = 0;
        
if (i == 0)
        
{
            
return "0";
        }

        
while (i > 0)
        
{
            digit 
++;
            
int low = i % 10;
            i 
/= 10;
            sb.setCharAt (
10 - digit, (char)(sb.charAt(10 - digit) + low));
        }

        
return sb.substring(10 - digit);
    }

    
// 求正整数的平方根的整数部分 (这个是抄自 Hacker's Delight 一书的)
    static int isqrt (int x)    // 0 <= x <= 2 ^ 31 -1
    {
        
int b, m = 0x40000000, y = 0;
        
while (m != 0)
        
{
            b 
= y | m;
            y 
>>= 1;
            
if (x >=b)
            
{
                x 
-= b;
                y 
|= m;
            }

            m 
>>= 2;
        }

        
return y;
    }

    
    
public static void main (String[] args) throws IOException
    
{
        BufferedReader br 
= new BufferedReader(
                
new InputStreamReader(System.in)
                );
        String str 
= br.readLine ();
        BigInteger bi [] 
= new BigInteger [3];
        bi [
0= new BigInteger (str);    // bi [0] 保存需要求平方根的数 X
        int len = str.length ();
        
// 如果 X 小于 1000000000,那么直接求平方根的整数部分
        if (len < 10)
        
{
            System.out.println (isqrt (str2int (str)));
            
return;
        }

        
// 如果 X 的位数是奇数,high 等于 X 的最高位,否则等于最高两位
        int high = str.charAt(0- '0';
        
if (len % 2 == 0)
        
{
            high 
= high * 10 + str.charAt(1- '0';
        }

        
// 将 high 的平方根的整数部分加上 1 之后乘以 10^((len - 1) / 2)
        
// 乘积不小于 X 的平方根的整数部分,保存到 char [] ch 中
        
// 然后赋值到 bi [1]
        int r = isqrt (high) + 1;
        
int zeros = (len - 1>> 1;
        str 
= int2str (r);
        r 
= str.length ();
        
char ch [] = new char [r + zeros];
        
for (int i = 0; i < r; i ++)
        
{
            ch [i] 
= str.charAt (i);
        }

        
for (int i = r; i < ch.length; i ++)
        
{
            ch [i] 
= '0';
        }

        bi [
1= new BigInteger (new String (ch));
        
// 牛顿迭代过程: X_k+1 = (X_k ^ 2 + X) / (X_k * 2)
        
// 通过 i = 3 - i ,可使 bi [1] 和 bi [2] 轮流保存 X_k, X_k+1
        
// 当 X_k+1 >= X_k 时, X_k 即为 X 的平方根的整数部分
        int i = 1;
        
do
        
{
            bi [
3 - i] = bi [i].pow(2).add (bi [0]).divide (bi [i].shiftLeft (1));
            i 
= 3 - i;
        }
 while (bi [i].compareTo (bi [3 - i]) == -1);
        System.out.println (bi [
3 - i]);
    }

}


在 SGU 提交的结果:
ID:     Date'n'Time:     Name:     Task:     .Ext:     Status:     Time:     Memory:
652002    28.10.07 02:20    rappizit    111     .JAVA    Accepted    126 ms    0 kb
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值