java大数详解

引论

在算法竞赛中我们经常遇到大数问题,例如求一个很大的斐波那契数。住在这种情况下我们正常作解(使用long long或long long int)肯定是不行的,而我们自己写一个大数的算法又过于麻烦且易于出错,在这种情况下使用java中自带的大数类是我们最好的选择

介绍

java中用于操作大数的类主要有两个,一个是BigInteger,代表大整数类用于对大整数进行操作,另一个是BigDecimal,代表高精度类,用于对比较大或精度比较高的浮点型数据进行操作。因为这两种类的使用方法是一样的,所以下面我们一BigInteger为例进行讲解

基本用法

1、新建一个值为123的大整数对象
BigInteger a=new BigInteger(“123”); //第一种,参数是字符串
BigInteger a=BigInteger.valueOf(123); //第二种,参数可以是int、long

2、大整数的四则运算
a. add(b); //a,b均为BigInteger类型,加法
a.subtract(b); //减 法
a.divide(b); //除法
a.multiply(b); //乘法

3、大整数比较大小
a.equals(b); //如果a、b相等返回true否则返回false
a.comareTo(); //a小于b返回-1,等于返回0,大于返回1

4、常用方法
a.mod(b); //求余
a.gcd(b); //求最大公约数
a.max(b); //求最大值
a.min(b); //求最小值

输入框架

    Scanner cin = new Scanner(System.in); //读入
    while(cin.hasNext()){  //等同于!=EOF
        BigInteger a;
        a = cin.BigInteger();   //读入一个BigInteger;
        System.out.println(a);   //输出a并换行
    }

注意

使用java大数类解决问题时我们需要注意两个方面
1、不能有包名,也就是说我们要把主类放到默认的包里,如果你的代码里出现形如package cn.gov.test;这样的代码你很有可能会收获到RE
2、提交的类的类名必须为Main,如果是其他的名字你有可能收获到CE也有可能收获到WA(例如UVA)

例题

光说不练假把式,学习了理论之后我们更需要编码练习,下面是我挑选的几个例题,希望能帮助到你

1、A-B Problem
题目描述:给你一个很大的a和b,判断a-b是否等于0
分析:亦即判断a与b是否相等,无任何难度的简单题,当然前提是你会java中的大数类
我的代码


import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;


public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin = new Scanner(System.in);
        BigDecimal a, b;
        while(cin.hasNext())
        {
            a = cin.nextBigDecimal();
            b = cin.nextBigDecimal();
            if(a.compareTo(b) == 0)
                System.out.println("YES");
            else
                System.out.println("NO");
            cin.nextLine();
        }

    }

}        

2、大数阶乘
题目描述:给你一个n,计算n的阶乘,但是n很可能比较大
分析:学会java大数后这就是一道不折不扣的水题,新手找找AC的快感吧
我的代码

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static BigInteger getTac(BigInteger a)
    {
        if(a.compareTo(new BigInteger("1")) <= 0)
            return new BigInteger("1");
        else
            return a.multiply(getTac(a.subtract(new BigInteger("1"))));
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin = new Scanner(System.in);
        BigInteger m;
        while(cin.hasNext())
        {
            m = cin.nextBigInteger();
            m = getTac(m);
            System.out.println(m);
        }

    }

}        

3、大菲波数
题目描述:计算第n项Fibonacci数值,n可能比较大
分析:这个题与之前的两个水题相比有了一定的含金量,直接按定义求解是会收获TLE的,所以我们需要用递推加打表
我的代码

import java.math.BigInteger;
import java.util.Scanner;


public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Scanner cin = new Scanner(System.in);

        BigInteger[] nums = new BigInteger[1010];
        nums[1] = new BigInteger("1");
        nums[2] = new BigInteger("1");
        for(int i = 3; i <= 1000; i++)
            nums[i] = nums[i - 1].add(nums[i - 2]);

        int T = cin.nextInt();
        while(T > 0)
        {
            T--;
            int n = cin.nextInt();
            System.out.println(nums[n]);
        }

    }

}

4、A/B

Problem Description
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
 

Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
 

Output
对应每组数据输出(A/B)%9973。
 

Sample Input
   
   
2
1000 53
87 123456789
 

Sample Output
   
   
7922
6060

分析:最容易想到的方法莫过于让n一直加9973加到n Mod b == 0,不过很可惜这样做会超时的;所以我们换一种思路,因为a一定能被b整除,所以a一定是b的倍数,于是我们让a = b * i(i= 1,2,3···)直到a Mod b == n;此时得到大整数a直接用题目中给的公式就能将正确答案做出来

我的代码

import java.math.BigInteger;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner cin = new Scanner(System.in);
        int T = cin.nextInt();
        while(T > 0)
        {
            T--;
            BigInteger a = cin.nextBigInteger();
            BigInteger b = cin.nextBigInteger();
            BigInteger d = new BigInteger("9973");
            BigInteger z = new BigInteger("0");


            for(BigInteger i = new BigInteger("1"); ; i = i.add(new BigInteger("1")))
            {
                BigInteger c = b.multiply(i);
                if(c.mod(d).compareTo(a) == 0)
                {
                    System.out.println(i.mod(d));
                    break;
                }
            }
        }

    }

}

猜你喜欢

转载自blog.csdn.net/dongchengrong/article/details/78848399